PictureBox中的鼠标滚轮事件?

7

我希望能够在图片框(或所有图片和主窗体)上悬停并使用鼠标滚轮滚动。但是我没有成功。我编写了pictureBox1.MouseWheel并检查delta。我设置了一个断点,当它!= 0时会触发。到目前为止,无论我做什么,都无法使其起作用。我也尝试了mousemove,但是也不起作用。然而,在if语句上打断点可以正常工作。我只是永远无法让滚轮起作用。

如何使图片框(或窗体中的任何控件)调用鼠标滚轮事件?

-编辑- 没关系。我将事件添加到大多数时间具有该事件的对象中。这相当有效。我不确定为什么在编写此问题之前我没有想到这一点。我仍然接受鼠标悬停+轮子解决方案。


1
我知道这个问题很老了。但是在Windows 10中已经有所改变。在Windows 10中,鼠标悬停的所有控件都会接收到鼠标滚轮事件。 - LxL
5个回答

13

Windows不会将鼠标滚动消息发送给悬停的控件,而是发送给具有焦点的控件。您已经知道如何修复焦点。

由于浏览器和Office程序的工作方式,这种行为变得不太直观。在此线程中,您可以找到修改此行为的代码。请注意,它适用于应用程序中的任何窗口。如果不需要,则必须添加句柄值过滤器。


更新:Win10中更改了此行为。它具有一个名为“当我悬停在非活动窗口上时滚动”的新系统设置,默认情况下打开。因此,焦点不再重要,并且现在的行为与浏览器中的行为非常相似。测试您的应用程序很重要,您可以通过临时禁用系统选项来查看在较旧的Windows版本上会发生什么。


非常好的回答。你真的帮助了我解决所有GUI方面的需求。 - user34537

2

这篇回答 解释了如何实现它。简单来说,给图片框创建一个鼠标进入事件,让其聚焦在图片框上。然后,图片框就可以正常接收鼠标滚轮事件了。


你绝不能因为鼠标移动而从用户那里夺走键盘焦点!这真的是一个非常非常丑陋的解决方法。不要这样做!除此之外,它对我也没有用。即使我将焦点设置到pictureBox上,我也无法获得滚轮事件。 - Elmue

1

这里的答案对我没有用。

我在可滚动面板中有一个picturebox,需要做更多工作才能正确运行。

你需要覆盖Form中的OnMouseWheel()函数。在那里,你可以获取鼠标滚轮事件,并检查鼠标是否在picturebox内。但这还不够。想象一下,你正在显示一个5000 x 5000像素的图像,它在一个只显示图像一小部分的可滚动面板中。那么你还必须检查鼠标是否在Pane及其所有父级上。下面的代码与pictureBox的任何父控件的滚动条位置无关。

/// <summary>
/// This must be overridden in the Form because the pictureBox never receives MouseWheel messages
/// </summary>
protected override void OnMouseWheel(MouseEventArgs e)
{
    // Do not use MouseEventArgs.X, Y because they are relative!
    Point pt_MouseAbs = Control.MousePosition; 
    Control i_Ctrl = pictureBox;
    do
    {
        Rectangle r_Ctrl = i_Ctrl.RectangleToScreen(i_Ctrl.ClientRectangle);
        if (!r_Ctrl.Contains(pt_MouseAbs))
        {
            base.OnMouseWheel(e);
            return; // mouse position is outside the picturebox or it's parents
        }
        i_Ctrl = i_Ctrl.Parent;
    }
    while (i_Ctrl != null && i_Ctrl != this);

    // here you have the mouse position relative to the pictureBox if you need it
    Point pt_MouseRel = pictureBox.PointToClient(pt_MouseAbs);

    // Do your work here
    ....
}

0

如果 PictureBox 不在窗体的 0,0 位置,则此方法仍有效。

' =====================================================================================
'  Windows10 has a new system setting 
'   named "Scroll inactive windows when I hover over them", turned on by default.
' -------------------------------------------------------------------------------------
'  The following correction does the same for Windows 8 / 7 / XP
' =====================================================================================
Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
    Dim p As Point
    p = pbox_Graph.PointToClient(Me.PointToScreen(e.Location))
    If pbox_Graph.ClientRectangle.Contains(p) Then
        pbox_TimeGraph_MouseWheel(Me, e)
    Else
        MyBase.OnMouseWheel(e)
    End If
End Sub

0
只需覆盖表单的MouseWheel并检查e.X和e.Y是否在PictureBox的位置区域内即可。
  protected override void OnMouseWheel(MouseEventArgs e)
    {
        if (e.X >= soundGraph.Location.X && e.X <= soundGraph.Location.X + soundGraph.Width
            &&
            e.Y >= soundGraph.Location.Y && e.Y <= soundGraph.Location.Y + soundGraph.Height)
        { // do what you have to
        }
        base.OnMouseWheel(e);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接