Windows 10 上出现垂直或水平滚动条时不调用鼠标事件
Mouse event is not called when vertical or horizontal scroller appear on Windows 10
我在System.Windows.Forms.Panel
里面有一个System.Windows.Forms.PictureBox
。 Panel
有:
- 固定维度
AutoScroll=true
- 事件处理程序订阅了
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
中的 PictureBox
。 TextBox
的目的只是为了在您单击 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");
}
}
我在System.Windows.Forms.Panel
里面有一个System.Windows.Forms.PictureBox
。 Panel
有:
- 固定维度
AutoScroll=true
- 事件处理程序订阅了
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
中的 PictureBox
。 TextBox
的目的只是为了在您单击 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");
}
}