Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF - Force ShowDialog to return

How can I force ShowDialog to return from a background thread?

I have a WPF application built on top of a C++/CLR framework which is listening to messages sent by the framework. One particular message is so important that I need to close all the current windows. However, if a modal Dialog (created by ShowDialog from my main window) is active and awaiting user input, the window will not close because it is waiting for ShowDialog to return. How can I force the modal Dialog to close and unwind code execution?

I tried setting the DialogResult or calling Close however that doesn't seem to work.

Edit: The Dialog is created by my main window which expects a return value, like so: (inside a click event handler in MainWindow):

Window modalDialog = new Window();
bool ret = (bool)modalDialog.ShowDialog();
if (ret == true)
{
 // do stuff
}
else
{
 // do some other stuff
}

When the framework sends a message (coming in on a different thread than the UI thread), I call MainWindow.Close(). The modal dialog gets closed at this point, however the code checking the return value of the Dialog (after ShowDialog) is still on the stack. Somehow this forces the main window to not disappear.

like image 206
Hypherion Avatar asked Jan 09 '10 00:01

Hypherion


1 Answers

When the dialog receives the WM_CLOSE message it sets a flag that causes ShowDialog to return after the WM_CLOSE and any containing messages have been fully processed. So if you are doing a Dispatcher.Invoke() onto your thread to call MainWindow.Close(), the ShowDialog() won't return until after the Dispatcher.Invoke() has completed.

So the simple solution is to return from the Dispatcher.Invoke() to get the ShowDialog() to return. If more processing is required, do another Dispatcher.Invoke() immediately afterwards.

If you are doing the thread transition some other way than Dispatcher.Invoke(), or if the ShowDialog() doesn't return after the Dispatcher.Invoke() call returns, you may have to post some of the code surrounding your Window.Close() call so we can see what you are actually doing.

like image 85
Ray Burns Avatar answered Sep 29 '22 00:09

Ray Burns