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



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

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

在放大/缩小时,我更改了PictureBox的暗淡,如果超过Panel的暗光,则自AutoScroll=true以来显示垂直和/或水平滚动。

现在,在Windows 7(我有企业版(上,一旦出现任何或两个滚动条并且我继续使用鼠标滚轮放大,订阅的事件处理程序将继续调用MouseWheel并且图像变大。
但是,在 Windows 10(我有家庭版(上,如果出现任何滚动条,事件处理程序将停止调用,滚动条接管。这意味着图像向上/向下或向左/向右滚动。

OP 已在评论中确认禁用 Win10 鼠标设置"将鼠标悬停在非活动窗口上时滚动非活动窗口"可以解决此问题,但我相信这也可以通过防止 MouseWheel 事件冒泡到包含Panel控件来处理。 要求用户更改其首选设置以使代码功能从来都不是可取的情况。

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

最新更新