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

C# 当垂直或水平滚动条出现在Windows 10上时,不会调用鼠标事件,c#,winforms,mousewheel,C#,Winforms,Mousewheel,我有一个System.Windows.Forms.PictureBox内置System.Windows.Forms.Panel。面板具有: 固定尺寸 AutoScroll=true 事件处理程序订阅了用于放大或缩小的鼠标滚轮 在放大/缩小时,我更改图片框的dims,如果它超过面板的尺寸,则会显示垂直和/或水平滚动,因为AutoScroll=true 现在,在Windows 7(我有企业版)上,一旦出现任何一个或两个滚动条,我继续用鼠标滚轮放大,将继续调用mouseweel订阅的事件处理程序,图像

我有一个
System.Windows.Forms.PictureBox
内置
System.Windows.Forms.Panel
面板
具有:

  • 固定尺寸
  • AutoScroll=true
  • 事件处理程序订阅了用于放大或缩小的
    鼠标滚轮
  • 在放大/缩小时,我更改
    图片框的dims
    ,如果它超过
    面板的尺寸,则会显示垂直和/或水平滚动,因为
    AutoScroll=true

    现在,在Windows 7(我有企业版)上,一旦出现任何一个或两个滚动条,我继续用鼠标滚轮放大,将继续调用
    mouseweel
    订阅的事件处理程序,图像将变大。

    但是,在Windows10(我有家庭版)上,如果出现任何滚动条,事件处理程序将停止调用,滚动条将接管。这意味着图像可以上/下或左/右滚动。

    OP在评论中确认,禁用Win10鼠标设置“当我将鼠标悬停在非活动窗口上时滚动它们”可以解决问题,但是,我相信这也可以通过防止鼠标滚轮事件冒泡到包含
    面板
    控件来处理。要求用户更改他们的首选设置以使您的代码发挥作用从来都不是理想的情况

    下面的代码演示如何防止此事件冒泡。只需创建一个新的Winform项目,并用以下代码替换Form1代码。该代码创建一个
    文本框
    ,以及一个
    面板
    中包含的
    图片框
    TextBox
    的作用只是在单击
    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");
        }
    }
    

    参考资料:

    请始终提供代码。然后打开一个新项目,重新创建相同的情况。如果你不能在那里重建它,那么你还有其他一些我们仍然看不到的东西在进行。还是最好把它简化成一个#mcve-为了你自己,也为了几十个左右的人,他们会点击这个想法“如果他/他准备好了一个复制,我可能会帮上忙”。此外,通过收集一个简单的例子,80%的时间你都会自己发现这个问题(然后你可以发布一个自我回答的Q&a),或者你会发现一个bug,然后你可以很容易地为它发送一份好的bug报告。剩下的时间像我这样的人都愿意帮忙!现在,虽然,我在路上…谷歌。这是第一次点击。Win10有鼠标设置“当我将鼠标悬停在非活动窗口上时滚动它们”,如果我没记错的话,直到Win8才显示。这可能是问题的一部分。您订阅的是谁的
    mouseweel
    事件(面板或图片盒)?此事件冒泡到控件的容器,但可以通过将事件参数强制转换为并将
    Handled
    属性设置为true来防止此事件。我知道这不是一个理想的解决方案,但在本例中,它是供内部使用的。用户以我们配置的方式获得硬件和软件。因此,没有人会要求用户更改任何内容。