WPF - заставить ShowDialog вернуться - PullRequest
6 голосов
/ 09 января 2010

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

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

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

Edit: Dialog создается моим главным окном, которое ожидает возвращаемое значение, например так: (внутри обработчика события щелчка в 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 ]

3 голосов
/ 12 января 2010

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

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

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

1 голос
/ 09 января 2010

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

SomeGenerator IG = Manager.SomeGenerator();
SomeWindow PP = new SomeWindow();
IG.ProgressEvent += PP.ProgressEvent;
IG.ExecuteAsync();            
PP.ShowDialog();
0 голосов
/ 13 января 2010

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

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

...