28

How to capture mouse wheel on panel in C#? I'm using WinForms

EDIT:

I try to do it on PictureBox now.

My code:

this.pictureBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);    
this.pictureBox1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)  
  {  
    MessageBox.Show("Click");  
  }

Clicking works. Wheelling doesn't. Why?

Mohammad Jafar Mashhadi
  • 4,102
  • 3
  • 29
  • 49
Miko Kronn
  • 2,434
  • 10
  • 33
  • 44

5 Answers5

39

If you can't see the "MouseWheel" event on a component, then you need to create it manually. Also, we need to focus that component, otherwise the "MouseWheel" event will not work for that component. I will show you how to create a "MouseWheel" event for "pictureBox1" and how it works.

  1. INSIDE THE CONSTRUCTOR, create a mousewheel event on that component.

    InitializeComponent();
    this.pictureBox1.MouseWheel += pictureBox1_MouseWheel;
    
  2. CREATE THE FUNCTION manually. According to my example, call it "pictureBox1_MouseWheel"

    private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
    {
        //you can do anything here
    }
    
  3. CREATE a MouseHover event on that component (Go to properties in PicureBox1, select event, locate "MouseHover" and double-click the "MouseHover" event).

  4. CALL "Focus()"; method inside that MouseHover event.

    pictureBox1.Focus();
    
  5. Now run the program.

Jim Simson
  • 2,774
  • 3
  • 22
  • 30
Shehan Silva
  • 526
  • 4
  • 8
  • 1
    A w e s o m e guy! In my case I dont need the `Mouse/Scroll EventArgs` so I've set `private void EventFunc(object sender, EventArgs e)`. This way I can set up both handlers (scroll and mousewheel) on the same function :). Clean. – C4d Mar 31 '16 at 15:39
  • 2
    This can create a very unexpected behavior, if you click into a textBox or want to edit something else this will focus the panel if you hover into it. I would not do this.. – Denny Apr 21 '17 at 14:53
  • 1
    Just to add some further edification on this one, e.Delta will return the direction of the scroll wheel by way of a positive or negative int. – Jim Simson Dec 20 '17 at 01:42
22

Windows sends the WM_MOUSEWHEEL message to the control that has the focus. That won't be Panel, it is not a control that can get the focus. As soon as you put a control on the panel, say a button, then the button gets the focus and the message.

The button however has no use for the message, it's got nothing to scroll. Windows notices this and sends the message to the parent. That's the panel, now it will scroll.

You'll find code for a custom panel that can get the focus in this answer.


UPDATE: note that this behavior has changed in Windows 10. The new "Scroll inactive windows when I hover over them" option is turned on by default. The makes the mouse wheel behavior more consistent with the way it works in a browser or, say, an Office program. In this specific case the picturebox now will get the event. Watch out for this.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
8

To wire it up manually...

this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);

private void panel1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
    ///process mouse event
}

Easier method is in visual studio click on panel, goto properties viewpanel, select events, locate and double click the "mousewheel" event.

Gerald Davis
  • 4,541
  • 2
  • 31
  • 47
  • 3
    I cannot see mousewheel. There is MouseCaptureChanged, MouseClick, MouseDoubleClick, MouseDown, MouseEnter, MouseHover, MpouseLeave, MouseMove, MouseUp – Miko Kronn Dec 13 '10 at 15:06
  • 1
    Weird you are right. Not sure why Visual Studio doesn't have it listed. If you wire it up manually it works. Here is a example program using MouseWheel event. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousewheel.aspx – Gerald Davis Dec 16 '10 at 14:26
  • 2
    Fwiw, it doesn't show up in the Properties viewpanel because the declaration of this event is decorated with "[Browsable(false)]". Also, it won't show up in IntelliSense's autocomplete panel unless VS is set up to show advanced members (i believe VB hides these, while C# doesn't by default) - and this happens because it's also decorated with "[EditorBrowsable(EditorBrowsableState.Advanced)]". – C.B. Apr 27 '13 at 15:53
  • @C.B. do you happen to know any reason for it being decorated so ? – Ciprian Tomoiagă Jul 19 '16 at 14:07
5

In Winforms, this is achieved using the Control.MouseWheel event

Ian Nelson
  • 57,123
  • 20
  • 76
  • 103
1

Getting mousewheel events is tricky. The easiest way is using

this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);

instead of

this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);

This way the form gets the event instead of control. This way is easy but has one problem: you can use only one mousewheel event in your form.

If you have more than one control to get mousewheel event the best way is This answer by "Shehan Silva - weltZ"

Community
  • 1
  • 1
Mokhabadi
  • 302
  • 2
  • 14