2010-01-09 61 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