2010-01-09 57 views
6

如何強制ShowDialog從後臺線程返回?WPF - 強制ShowDialog返回

我有一個基於C++/CLR框架構建的WPF應用程序,該框架正在監聽框架發送的消息。一條特別的信息非常重要,我需要關閉所有當前的窗口。但是,如果模式Dialog(由我的主窗口中的ShowDialog創建)處於活動狀態並等待用戶輸入,則該窗口將不會關閉,因爲它正在等待ShowDialog返回。如何強制模式Dialog關閉和展開代碼執行?

我嘗試設置DialogResult或致電Close但是,似乎沒有工作。

編輯:Dialog是由一個希望返回值,像這樣我的主窗口中創建: (在MainWindow點擊事件處理中):

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

當框架發送消息(未來在與UI線程不同的線程上),我打電話MainWindow.Close()。此時模式對話框會關閉,但檢查Dialog返回值(在ShowDialog之後)的代碼仍在堆棧中。不知何故,這迫使主窗口不消失。

回答

3

當對話框接收它設置導致的ShowDialog返回後WM_CLOSE和任何含消息已經被完全處理的標誌WM_CLOSE消息。因此,如果您正在將線路Dispatcher.Invoke()撥到MainWindow.Close()ShowDialog()將不會返回,直到Dispatcher.Invoke()完成。

所以簡單的解決辦法是從Dispatcher.Invoke()返回以獲得ShowDialog()返回。如果需要更多處理,請立即執行另一個Dispatcher.Invoke()

如果你正在做的線程轉變一些其他的方式比Dispatcher.Invoke(),或者如果ShowDialog()的Dispatcher.Invoke()調用返回後不回,你可能要發佈一些代碼周圍您Window.Close()電話,所以我們可以看到你在做什麼。

1

你不能強制ShowDialog返回,但你可以讓窗口監聽你的框架發送的事件,它可以告訴它關閉。在下面的例子中,Progress事件有一個「完成」標誌,完成後關閉窗口。

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

我編輯了我的原始問題,以表明ShowDialog預計會返回一個值,並且父窗口應該使用該值執行一些處理... – Hypherion 2010-01-11 19:44:26

0

我意識到現在我無法強制ShowDialog返回並在我需要時繼續執行。我從框架接收到的請求的事件處理程序需要超出上下文範圍,因此可以展開調用堆棧並且模態對話框可以處理關閉消息。

我結束了設置布爾標誌,請求模式關閉,然後從我的框架事件處理程序返回。只有在此時ShowDialog纔會返回,我可以檢查我設置的標誌並繼續執行所請求的操作。

+0

聽起來像我的回答是正確的,並幫助您解決問題。如果你同意你應該爲未來的訪問者標記爲「正確」。 – 2010-01-13 01:42:16