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() を呼び出すと、ボタンクリックが発生します。

私の実際のアプリケーションはもう少し複雑ですが、単純なテキスト ボックスとボタンを使用してこの動作をシミュレートしようとしました。実際のアプリケーションでは、ディスパッチャーに投稿されたバックグラウンド ワーカー スレッドの 1 つがモーダル メッセージ ボックス (または WPF フォーム) を表示し、キュー内の UI 保留中のメッセージはすべてメッセージ ボックスによって処理されるようです (私は疑っています)。たとえば、キャンバス コントロールをクリックすると理想的には、「Mouse Down」と「Mouse Up」を取得しますが、モーダルメッセージボックスがこの 2 つのメッセージの間にある場合、「Mouse Down」と「Mouse Up」のメッセージのみが表示されます。

注:非モーダル ダイアログの場合、この動作が見られないことはわかりません。

また、モーダル ダイアログと非モーダル ダイアログの場合に、Windows フォームが Windows メッセージ ポンプをどのように処理するかについての素敵な記事を誰かが私に指摘してくれれば、私の知る限りでも役に立ちます。

4

2 に答える 2

0

DispatcherPriorityメソッドのパラメーターを使用して、ディスパッチャーアクションに必要な優先度を設定できますBeginInvoke()。私が通常使用する最低の優先度はApplicationIdleです。したがって、ディスパッチャは、保留中のすべての操作を処理してから処理を完了することができます。

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