tags:

views:

1597

answers:

5

I'm building a windows form in C# with VS2008.I have about 32 buttons, I've placed an image over the default buttons, but I want to have a Hover/Up/Down effect for each of these buttons, and I can't seem to find this information anywhere.

Perhaps I'm searching for the wrong terms, any direction is appreciated.

+1  A: 

Sounds like a job for inheritance to me. I'd subclass a button class and handle the hover, press, and leave by overriding the OnHover, OnPress, OnLeave, and OnPaint methods. Do your button painting in OnPaint.

Darthg8r
A: 

I have made a program which needed this with some labels, the result I came up with (add the AddHandles()-void to Form_Load):

    private void AddHandles()
    {
        foreach (Control c in this.Controls)
        {
            if (c.GetType() == typeof(Button))
            {
                c.MouseEnter += new EventHandler(ButtonEnter);
                c.MouseLeave += new EventHandler(ButtonLeave);
                c.MouseDown += new MouseEventHandler(ButtonDown);
                c.MouseUp += new MouseEventHandler(ButtonUp);
            }
        }
    }
    private void ButtonEnter(object sender, EventArgs e)
    {
        ((Button)sender).BackColor = Color.DarkGray;
        ((Button)sender).Cursor = System.Windows.Forms.Cursors.Hand;
    }
    private void ButtonLeave(object sender, EventArgs e)
    {
        ((Button)sender).BackColor = Color.Black;
        ((Button)sender).Cursor = System.Windows.Forms.Cursors.Default;
    }
    private void ButtonDown(object sender, MouseEventArgs e)
    {
        ((Button)sender).BackColor = Color.Gray;
    }
    private void ButtonUp(object sender, MouseEventArgs e)
    {
        ((Button)sender).BackColor = Color.Black;
        ((Button)sender).Cursor = System.Windows.Forms.Cursors.Default;

        //Code to be executed 
        //Use the name/text/etc of the Button to figure what to do...
    }

Note that I originally used this with Labels, so there may be need for some changes.

Phoexo
Having 34 instances cries for inheritance and not assigning the event handlers in for loop!
Tamás Szelei
+2  A: 

Inherit from the System.Windows.Forms.Button class, and override the following methods:

  • OnMouseDown, this handles your "Pressed Image"
  • OnMouseEnter, this handles your "Hovering Image"
  • OnMouseLeave, and this handles your original image

The code would look something like this:

public class MyButton : System.Windows.Forms.Button {
    public MyButton()
        : base() {
        // No default implementation
    }

    protected override void OnMouseDown(Object sender, MouseEventArgs e) {
        this.Image = Properties.Resources.PressedImage;
    }

    protected override void OnMouseEnter(Object sender, MouseEventArgs e) {
        this.Image = Properties.Resources.HoveringImage;
    }

    protected override void OnMouseLeave(Object sender, MouseEventArgs e) {
        this.Image = Properties.Resources.DefaultImage;
    }
}

Now since you have multiple buttons, you could of course turn the resource acquisitions into properties.

public Image DefaultImage {
    get;
    set;
}

public Image PressedImage {
    get;
    set;
}

public Image HoveringImage {
    get;
    set;
}

And use those in the overridden, virtual methods. This is probably your best approach. I would avoid the answer below (no offense Phoexo) as it is a very unusual and messy solution.

Once you write and compile the new button, you can do a simple find and replace to change the existing button's types. You will have to do a little cleanup and set the three properties for each button to their corresponding images, and cleanup some designer code, but this will make your life easier in the long run if you have to add more buttons.

David Anderson
Thank you this is working beautifully. Thanks to all.
Sacrilege
A: 

I implemented it much similarly to David Anderson's solution once, but I kept record of the actual state and overrided the OnPaint method to paint the proper image. I don't know if it's better in any way, it's just how I did this.

Tamás Szelei
A: 

Use a Check Box or a Radio Button and then change the Appearance to Button. You can add an image to the Check Box or Radio Button just like a regular Button.

The setting can be set in either the Designer or via code:

CheckBox checkBox = new CheckBox(); checkBox.Appearance = Appearance.Button;