FlatStyle.System引发奇怪的MouseHover事件

时间:2012-12-28 06:29:30

标签: c# winforms

使用以下代码,当我将鼠标移动到按钮并单击它时,结果的最终值为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才会在单击按钮后再触发MouseHover。 如果FlatStyle of button按钮最初是FlatStyle.System,则给出 result = 1 ; 如果FlatStyle更改为其他Style(弹出,平面),请提供 result = 1 ;

  3. 所以我想问题就在于FlatStyle设置为FlatStyle.System,任何人都可以向我解释这个问题吗?

1 个答案:

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