8

I'm trying to create a button in my .NET 4.0 Winforms app in Visual Studio 2010 that is ONLY an image. I have a window that is borderless and has a background image that makes up my custom skin for this application. For the close/minimize buttons in the top right of the window, I wanted to create 2 simple buttons that are images only that look like the typical Windows close/minimize buttons.

I may be going about this design wrong, so if I am please let me know. So far I've determined that I need to create a subclass for Button that only renders the image. The final implementation needs to render different images for each button state (normal, hover, clicked, etc). Here is what I have so far:

public class ImageButton : Button
{
    Pen pen = new Pen( Color.Red, 1.0f );

    public ImageButton()
    {
        SetClientSizeCore( BackgroundImage.Width, BackgroundImage.Height );
    }

    protected override void OnPaint( PaintEventArgs e )
    {
        e.Graphics.DrawImage( BackgroundImage, 0, 0 );
        //e.Graphics.DrawRectangle( pen, ClientRectangle );
        //Rectangle bounds = new Rectangle( 0, 0, Width, Height );
        //ButtonRenderer.DrawButton( e.Graphics, bounds, PushButtonState.Normal );
        //base.OnPaint(pevent);
    }

    protected override void OnPaintBackground( PaintEventArgs e )
    {
        // Do nothing
    }
}

At this point, assuming this design is appropriate, I need to know how to call SetClientSizeCore() appropriately. Calling it in the constructor raises an exception. I assume this is because the control hasn't had a chance to initialize yet. I'm not sure what function to override that will allow me to change the size of my button to fit the image after it has been initialized by .NET. Any ideas on this?

1
  • 1
    Just been attempting this myself, but realised that a simpler workaround would be to use a PictureBox control instead, as it has a click event, and there wasn't anything else I needed particularly from the button object. Commented Sep 13, 2012 at 13:25

3 Answers 3

8

In the constructor, BackgroundImage is null.

You need to set the size when BackgroundImage is changed by overriding the property.

You should also shadow the Size property and add [DesignerSerializationVisibilty(DesignerSerializationVisibility.Hidden)] to prevent the size from being saved by the designer.

Sign up to request clarification or add additional context in comments.

5 Comments

Especially the DesignerSerializationVisibility element... I'm sure many miss that part.
When you say 'shadow' the Size property, you mean re-implement it and forward get/set to the base.Size? It's not virtual so I can't override it using the same means as BackgroundImage.
@Bob: Yes, using the new modifier.
Very useful. BTW, typo on designer atribute; should be: [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
@SLaks I just wanted to draw attention to the fact that there is still a typo in this post. It should be [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]. Note the addition of the last i in the first occurrence of Visibility (the change isn't enough characters for me to edit it myself).
1

Wait until the BackgroundImage property is assigned so you'll know what size you need. Override the property like this:

public override Image BackgroundImage {
    get { return base.BackgroundImage; }
    set {
        base.BackgroundImage = value;
        if (value != null) this.Size = value.Size;
    }
}

Comments

0

If you want to use ImageButtons, I'd recommend using BunifuUI as it has ImageButtons.

If you don't want to use BunifuUI, you can use a PictureBox as it also has a click event. Example:

private void pictureBox1_Click(object Sender, EventArgs e) {
   webBrowser1.Navigate("https://www.google.com");
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.