使用以下代码,当我将鼠标移动到按钮并单击它时,结果的最终值为2而不是1.
static int result = 0;
private void button2_MouseHover(object sender, EventArgs e)
{
result++;
}
private void button2_MouseDown(object sender, MouseEventArgs e)
{
button2.FlatStyle = FlatStyle.System;
}
我尝试了不同的设置:
使用 MouseEnter 代替 MouseHover ,提供 result = 1
只有将FlatStyle更改为System才会在单击按钮后再触发MouseHover。 如果FlatStyle of button按钮最初是FlatStyle.System,则给出 result = 1 ; 如果FlatStyle更改为其他Style(弹出,平面),请提供 result = 1 ;
所以我想问题就在于FlatStyle设置为FlatStyle.System,任何人都可以向我解释这个问题吗?
答案 0 :(得分:2)
这是Winforms中相当常见的怪癖。您可以直观地了解此代码的内容:
private void button1_MouseHover(object sender, EventArgs e) {
Console.WriteLine("{0:X}, {1}", button1.Handle, DateTime.Now.TimeOfDay);
result++;
}
在“输出”窗口中查看显示的诊断。我的:
12780286, 03:04:10.7619696
12780286, 03:04:16.2935137
12780286, 03:04:20.1062178
12780286, 03:04:23.9970596
Click
12845822, 03:04:28.9191911
12845822, 03:04:32.3099880
请注意单击后Handle属性值的更改方式。换句话说,物理Windows窗口已更改。发生这种情况是因为您更改了FlatStyle属性。 Winforms通过销毁按钮控制窗口并重新创建它来实现此功能。如果你看起来很近,那么你实际上可以看到这个,按钮会短暂地闪烁。
有一些属性是这样实现的,它们是“重”属性,需要在样式标志更改后重新创建窗口。在本机CreateWindowEx()调用中传递的样式标志。这些样式标志的更改需要另一次调用CreateWindowEx()。
这往往会产生副作用。摧毁旧窗口会导致其状态丢失。 Winforms尝试尽可能地恢复新窗口的状态,但有一些它无法达到。 “窗口徘徊”状态就是其中之一。显然,新窗口将内部状态标志设置为false。这就是为什么你再次获得MouseHover事件。你需要解决这个问题。