FlatStyle.系统引发奇怪的鼠标悬停事件

本文关键字:鼠标 悬停 事件 系统 FlatStyle | 更新日期: 2023-09-27 17:49:39

使用下面的代码,当我将鼠标移动到按钮并单击它时,result的最终值是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;
}

我已经尝试了不同的设置:

  1. 使用MouseEnter代替MouseHover给出result = 1

  2. 仅将FlatStyle更改为System将在单击按钮后再次触发鼠标悬停。如果按钮的FlatStyle最初是FlatStyle。System, give result = 1;如果FlatStyle更改为others Style(popup, flat),则给出result = 1;

所以我猜问题在于FlatStyle设置为FlatStyle。系统,有人能解释一下吗?

FlatStyle.系统引发奇怪的鼠标悬停事件

这是一个在Winforms中相当常见的怪癖。您可以看到这段代码是怎么回事:

    private void button1_MouseHover(object sender, EventArgs e) {
        Console.WriteLine("{0:X}, {1}", button1.Handle, DateTime.Now.TimeOfDay);
        result++;
    }

在Output窗口中查看显示的诊断结果。我:

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事件。你需要解决这个问题。