6

I have a little problem with winforms and mousewheel events. I have a custom user control representing a slider. Now, I have a couple groups of sliders in which each group is wrapped inside a panel. All the groups are then wrapped in another panel (which has AutoScroll set to true) and this is wrapped in a form. The slider logic is implemented such that the mousewheel can be used to change its value. For this, the slider user control gets focus when the mouse is over the slider. However, when I scroll, also the AutoScroll parent panel scrolls with it. I've already lost a lot of time on this issue. Anybody knows what is happening here and how I can solve it? I thought the event was bubbling to the parent panel but I don't find a Handled property on the event when handling it in the Slider control (as is possible with WPF).

many thanks

Chris
  • 315
  • 3
  • 7
  • I thought scroll was only affected by which item had the focus, not just hovering above it. – MPelletier Aug 08 '11 at 14:39
  • @MPelletier it differs. For instance in outlook it's by hover, but in visual studio it is by focus – Oskar Kjellin Aug 08 '11 at 14:46
  • I focus my user control using a MouseEnter event. This way I can use the MouseWheel on my focussed slider UserControl. The wheel works perfect, the only problem is that the parent panel also scrolls at the same time. – Chris Aug 08 '11 at 14:56
  • What is a "slider"? I get no repro for this with a TrackBar inside a scrollable panel. – Hans Passant Aug 08 '11 at 15:48
  • @Hans Passant: We implemented the Slider as a complete custom user control (inheriting the UserControl class) with own look-and-feel. When the mouse hovers the control, we do a Select (focus) of the user control and then use the MouseWheel to change the value of the slider. This works perfectly except for the problem that the parent AutoScroll panel also scrolls. When the mouse leaves the user control, the focus is changed to the parent and the scrolling of the slider stops as expected when the mouse wheel is used. – Chris Aug 08 '11 at 18:49

2 Answers2

17

We implemented the Slider as a complete custom user control (inheriting the UserControl class) with own look-and-feel.

You might have noticed that a UserControl doesn't show the MouseWheel event in the Properties window. Hint of trouble there. The WM_MOUSEWHEEL message bubbles. If the control that has the focus doesn't handle it then Windows passes it on to its Parent. Repeatedly, until it finds a parent window that wants to handle it. The Panel in your case.

You'll need to invoke a bit of black magic in your slider control. The actual event args object that get passed to the MouseWheel event is not of the MouseEventArgs type as the event signature suggests, it is HandledMouseEventArgs. Which lets you stop the bubbling. Like this:

    protected override void OnMouseWheel(MouseEventArgs e) {
        base.OnMouseWheel(e);
        // do the slider scrolling
        //..
        ((HandledMouseEventArgs)e).Handled = true;
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Man, you are a life saver. Thank you so much for this. I find it disturbing I couldn't find this explained anywhere in the MS docs. Maybe I looked over it? – Chris Aug 09 '11 at 07:30
  • You didn't. You got into trouble by using UserControl instead of Control. – Hans Passant Aug 09 '11 at 08:38
0

If you are creating event dynamically like

object.event += new EventHandler<EventArgs>(eventfunction);

try un-registering the event after the eventfunction is called like this

object.event -= new EventHandler<EventArgs>(eventfunction);
Arjun Shetty
  • 1,575
  • 1
  • 15
  • 36