Windows 10 上出现垂直或水平滚动条时不调用鼠标事件

Mouse event is not called when vertical or horizontal scroller appear on Windows 10

我在System.Windows.Forms.Panel里面有一个System.Windows.Forms.PictureBoxPanel 有:

  1. 固定维度
  2. AutoScroll=true
  3. 事件处理程序订阅了 MouseWheel,用于放大或缩小

在 zoom-in/zoom-out 上,我更改了 PictureBox 的暗淡,如果它超过 Panel 尺寸,则显示垂直 and/or 水平滚动,因为 AutoScroll=true .

现在,在 Windows 7(我有企业版)上,一旦任何一个或两个滚动条出现并且我继续使用鼠标滚轮放大,MouseWheel 的订阅事件处理程序将继续调用,图像变大。
但是,在 Windows 10(我有家庭版)上,如果出现任何滚动条,事件处理程序将停止调用,滚动条将接管。表示图像滚动 up/down 或 left/right.

OP 在评论中确认禁用 Win10 鼠标设置 "Scroll inactive windows when I hover over them" 可以解决问题,但我相信这也可以通过防止 MouseWheel 事件冒泡到包含 Panel 控制。要求用户更改他们的首选设置以使您的代码正常运行绝不是理想的情况。

以下代码演示了如何防止此事件冒泡。只需创建一个新的 Winform 项目并将 Form1 代码替换为此。该代码创建了一个 TextBox 和一个包含在 Panel 中的 PictureBoxTextBox 的目的只是为了在您单击 PictureBox 时显示其失去焦点。对于 Win7,单击 PictureBox 将其激活,然后使用鼠标滚轮 increase/decrease PictureBox 大小。

public partial class Form1 : Form
{
    PictureBox pictureBox1;
    Panel panel1;

    public Form1()
    {
        InitializeComponent();
        Size = new Size(500, 500);
        Controls.Add(new TextBox() { TabIndex = 0, Location = new Point(350, 5)});
        panel1 = new Panel() {Size = new Size(300, 300), Location = new Point(5, 5), BorderStyle = BorderStyle.FixedSingle,Parent = this, AutoScroll = true};
        pictureBox1 = new PictureBox() {Size = new Size(200, 200) , Location = new Point(5,5), BorderStyle = BorderStyle.FixedSingle, Parent = panel1};
        pictureBox1.Click += pictureBox1_Click;
        pictureBox1.MouseWheel += pictureBox1_MouseWheel;
        panel1.MouseWheel += panel1_MouseWheel;
    }

    private void pictureBox1_Click(object sender, EventArgs e)
    {
        // On Win10 with "Scroll inactive windows when I hover over them" turned on,
        // this would not be needed for pictureBox1 to receive MouseWheel events

        pictureBox1.Select(); // activate the control
        // this makes pictureBox1 the form's ActiveControl
        // you could also use: 
        //   this.ActiveControl = pictureBox1;
    }

    private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
    {
        Rectangle r = pictureBox1.Bounds;
        int sizeStep = Math.Sign(e.Delta) * 10;
        r.Inflate(sizeStep, sizeStep);
        r.Location = pictureBox1.Location;
        pictureBox1.Bounds = r;

        // e is an instance of HandledMouseEventArgs
        HandledMouseEventArgs hme = (HandledMouseEventArgs)e;
        // setting to true prevents the bubbling of the event to the containing control (panel1)
        hme.Handled = true;
        // comment out the above line to observe panel1_MouseWheel
        // being called
    }


    private void panel1_MouseWheel(object sender, MouseEventArgs e)
    {
        System.Diagnostics.Debug.Print("bubbled wheel event");
    }
}

参考:HandledMouseEventArgs Class