0

我有一个带有文本框和按钮的简单 WPF 表单,在失去焦点时它只是简单地显示一个消息框。我的代码看起来像这样

   private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("Lost Focus 1");
        Dispatcher.BeginInvoke(new Action(() =>
               {
                   //Uncomment below lines to get button click
                   //Thread.Sleep(100);
                   //System.Windows.Forms.Application.DoEvents();
                   MessageBox.Show("Lost focus");
               }
            ));
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("Button_Click");
    }

如果我的文本框有焦点并且当我单击按钮时,如果显示消息框,则不会触发按钮单击,但是如果我在显示消息框之前调用 Application.DoEvents(),则我的按钮单击会被触发。

我的实际应用程序要复杂一些,但我试图用一个简单的文本框和一个按钮来模拟这种行为。在实际应用程序中,我的后台工作线程之一在调度程序上发布以显示模式消息框(甚至 WPF 表单),并且队列中的任何 UI 挂起消息似乎都由消息框(我怀疑)处理,例如,如果我单击画布控件理想情况下,我会得到“ Mouse Down ”和“ Mouse Up ”,但是如果在这 2 条消息之间出现模态消息框,那么我只会得到“ Mouse Down ”和“ Mouse Up ”消息丢失。

注意:在非模态对话框的情况下,我看不到这种行为。

另外,如果有人可以指出我的知识,关于 Windows 窗体如何在模态对话框和非模态对话框的情况下处理 Windows 消息泵的好文章会很有帮助。

4

2 回答 2

0

您可以使用方法的DispatcherPriority参数为Dispatcher 操作设置所需的优先级BeginInvoke()。我通常使用的最低优先级是ApplicationIdle,因此允许 Dispatcher 在处理您的操作之前完成其所有待处理操作的处理。

Dispatcher.BeginInvoke(new Action(() =>
{
   MessageBox.Show("Lost focus");
}), DispatcherPriority.ApplicationIdle);
于 2012-12-07T19:33:44.710 回答
0

文本控件在单击按钮之前失去焦点(可能在它甚至获得鼠标按下消息之前,不确定),导致显示 MessageBox。此调用的 MessageBox 是模态的,并在按钮获取使按钮“单击”的按钮向上消息之前禁用按钮。

模态对话框有自己的消息循环,因此它们不必立即从 ShowDialog 返回,但它们也会禁用它们的调用/所有者/父(我忘了哪个)窗口,直到它们返回。

这不是哪个消息循环正在处理鼠标按钮向上消息的问题,而是该消息的相对时间以及按钮控件被显示的模式表单禁用的问题。想想如果您单击并按住鼠标按钮一两秒钟会是什么时间。我怀疑您会发现 MessageBox 在您释放鼠标按钮之前出现。

于 2021-11-25T17:55:40.493 回答