如何强制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
之后)的返回值的代码仍在堆栈中。不知怎的,这迫使主窗口不会消失。
答案 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才会返回,我可以检查我设置的标志并继续执行请求的操作。