I have a simple WPF form with a textbox and button and on lost focus it simply simply shows a message box. My code looks like this
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");
}
If my textbox has focus and when I click on button then Button click is not fired if the messagebox is shown but if I call Application.DoEvents() before I show messagebox then my button click get fired.
My actual application is bit more complex but I have tried to simulate this behavior with a simple textbox and a button. In actual application one of my background worker thread post on dispatcher to show a modal messagebox (or even WPF form) and any UI pending messages in queue seems to be handled by messagebox (I suspect) so for e.g. If I click on a canvas control Ideally I get "Mouse Down" and "Mouse Up" but if a Modal messagebox comes in between this 2 message then I only get "Mouse Down" and "Mouse Up" message is lost.
Note: I don't see this behavior is not seen in case of Non-Modal dialogs.
Also just for my knowledge if someone can point me out on nice articles of how does windows forms handles windows message pump in case of Modal dialog and Non-Modal dialog would be helpful.
You can set the priority you want for your Dispatcher action using the DispatcherPriority
parameter of the BeginInvoke()
method. Lowest priority I usually use would be ApplicationIdle
, thus allowing the Dispatcher to finish processing all its pending operations before processing yours.
Dispatcher.BeginInvoke(new Action(() =>
{
MessageBox.Show("Lost focus");
}), DispatcherPriority.ApplicationIdle);