WPF-принудительно ShowDialog для возврата

как я могу заставить ShowDialog для возврата из фонового потока?

у меня есть приложение WPF, построенное поверх платформы C++/CLR, которая прослушивает сообщения, отправленные платформой. Одно конкретное сообщение настолько важно, что мне нужно закрыть все текущие окна. Однако, если модальный Dialog (созданные ShowDialog из моего главного окна) активен и ожидает ввода пользователя, окно не закроется, потому что оно ждет ShowDialog вернуться. Как я могу заставить модальный Dialog закрыть и размотать выполнение кода?

Я попытался установить DialogResult или позвонив Close однако это, похоже, не работает.

"Правка":Dialog создается моим главным окном, которое ожидает возвращаемое значение, например: (внутри обработчика событий click в MainWindow):

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

когда платформа отправляет сообщение (входящее в другой поток, чем поток пользовательского интерфейса), я вызываю MainWindow.Close(). Модальный диалог закрывается в этот момент, однако код проверка возвращаемого значения Dialog (после ShowDialog) все еще находится в стеке. Каким-то образом это заставляет главное окно не исчезать.

3 ответов


когда диалоговое окно получает сообщение WM_CLOSE, он устанавливает флаг, который вызывает ShowDialog для возврата после WM_CLOSE и все содержащие сообщения были полностью обработаны. Поэтому, если вы делаете Dispatcher.Invoke() на ваш поток для вызова MainWindow.Close() на ShowDialog() не вернется до тех пор, пока Dispatcher.Invoke() завершено.

таким образом, простым решением является возвращение из Dispatcher.Invoke() для получения ShowDialog() вернуться. Если требуется дополнительная обработка, выполните другое Dispatcher.Invoke() сразу впоследствии.

если вы делаете переход потока каким-то другим способом, чем Dispatcher.Invoke(), или ShowDialog() не возвращается после диспетчера.Invoke () Call returns, возможно, вам придется опубликовать часть кода, окружающего ваш Window.Close() звонок, чтобы мы могли увидеть, что вы на самом деле делаете.


вы не можете заставить ShowDialog вернуться, но вы можете заставить окно слушать событие, отправленное вашей платформой, которое может сказать ему закрыть. В приведенном ниже примере событие прогресса имеет флаг "готово", который закрывает окно, когда готово.

SomeGenerator IG = Manager.SomeGenerator();
SomeWindow PP = new SomeWindow();
IG.ProgressEvent += PP.ProgressEvent;
IG.ExecuteAsync();            
PP.ShowDialog();

теперь я понимаю, что не могу заставить ShowDialog вернуться и продолжить выполнение, когда захочу. Обработчик событий для запроса, который я получаю от фреймворка, должен выйти из контекста, чтобы стек вызовов можно было размотать и модальный диалог мог обработать сообщение закрытия.

в итоге я установил логический флаг, запросив модалы для закрытия, а затем вернулся из моего обработчика событий framework. Только в этот момент ShowDialog вернется, и я могу проверить флаг, который я установил и продолжайте выполнение запрошенных действий.