WPF - 强制ShowDialog返回

时间:2010-01-09 00:39:51

标签: c# .net wpf modal-dialog showdialog

如何强制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 个答案:

答案 0 :(得分:3)

当对话框收到WM_CLOSE消息时,它会设置一个标志,导致ShowDialog在WM_CLOSE之后返回,并且任何包含的消息都已完全处理。因此,如果您在线程上Dispatcher.Invoke()拨打MainWindow.Close()ShowDialog()将在Dispatcher.Invoke()完成后才会返回。

因此,简单的解决方案是从Dispatcher.Invoke()返回以使ShowDialog()返回。如果需要更多处理,请立即执行另一个Dispatcher.Invoke()

如果您正在以Dispatcher.Invoke()之外的其他方式进行线程转换,或者在Dispatcher.Invoke()调用返回后ShowDialog()未返回,则可能必须发布一些围绕Window.Close()来电的代码,以便我们了解您的实际行动。

答案 1 :(得分:1)

您不能强制ShowDialog返回,但您可以让窗口监听框架发送的事件,该事件可以告诉它关闭。在下面的示例中,Progress事件具有“完成”标志,完成后关闭窗口。

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

答案 2 :(得分:0)

我现在意识到我无法强制ShowDialog返回并在我想要的时候继续执行。我从框架接收的请求的事件处理程序需要退出上下文,以便可以解开调用堆栈,并且模式对话框可以处理Close消息。

我最终设置了一个布尔标志,请求关闭模态,然后从我的框架事件处理程序返回。只有在这一点上ShowDialog才会返回,我可以检查我设置的标志并继续执行请求的操作。