2009-12-01 91 views
5

我正在編寫一個應用程序(c#+ wpf),其中所有模式樣式對話框都作爲UserControl在覆蓋主要Window的半透明網格上實現。這意味着只有一個Window,它保持所有公司應用程序的外觀和感覺。仿真ShowDialog功能

要顯示MessageBox,語法如下:

CustomMessageBox b = new CustomMessageBox("hello world"); 
c.DialogClosed +=()=> 
{ 
    // the rest of the function 
} 
// this raises an event listened for by the main window view model, 
// displaying the message box and greying out the rest of the program. 
base.ShowMessageBox(b); 

正如你所看到的,不僅是執行的實際上是倒流量,但其可怕的詳細比較經典的.NET版本:

MessageBox.Show("hello world"); 
// the rest of the function 

我所真正需要的是一種方式,直到對話框關閉的事件已經被舉到不base.ShowMessageBox回來,但我不能看到它是如何可能要等待這個不掛GUI線程,因此阻止我們呃點擊確定。我知道我可以將一個委託函數作爲ShowMessageBox函數的一個參數,它可以防止執行的反轉,但仍然會導致一些瘋狂的語法/縮進。

我是否錯過了一些顯而易見的東西,或者有沒有一種標準的方法來做到這一點?

回答

5

您可能想看看this CodeProject上的文章和this文章在MSDN上。第一篇文章引導您手動創建阻止模式對話框,第二篇文章演示如何創建自定義對話框。

+0

鏈接的第一篇文章顯示瞭如何做到這一點的完美例子。 – Guy 2009-12-01 15:31:07

0

你可以讓你的函數成返回IEnumerator<CustomMessageBox>的迭代器,然後把它寫這樣的:

//some code 
yield return new CustomMessageBox("hello world"); 
//some more code 

你可以這樣寫一個包裝函數,它枚舉和調用MoveNext(將執行所有的直到DialogClosed處理程序中的下一個yield return)的功能。

請注意,包裝函數不會阻塞調用。

0

在消息框類中設置另一個消息循環。喜歡的東西:

public DialogResult ShowModal() 
{ 
    this.Show(); 

    while (!this.isDisposed) 
    { 
    Application.DoEvents(); 
    } 

    return dialogResult; 
} 

如果你看一下Windows.Form在反射器,你會看到它確實是這樣的..

+0

他使用WPF,而不是WinForms。 – SLaks 2009-12-01 15:18:30

+0

啊,我錯過了。 WPF是完全不同的? Windows不再有消息循環嗎? – 2009-12-01 15:30:32

4

做,這是通過使用DispatcherFrame對象的方式。

var frame = new DispatcherFrame(); 
CustomMessageBox b = new CustomMessageBox("hello world"); 
c.DialogClosed +=()=> 
{ 
    frame.Continue = false; // stops the frame 
} 
// this raises an event listened for by the main window view model, 
// displaying the message box and greying out the rest of the program. 
base.ShowMessageBox(b); 

// This will "block" execution of the current dispatcher frame 
// and run our frame until the dialog is closed. 
Dispatcher.PushFrame(frame);