6

如何强制ShowDialog从后台线程返回?

我有一个构建在 C++/CLR 框架之上的 WPF 应用程序,它正在侦听框架发送的消息。一条特定的消息非常重要,以至于我需要关闭所有当前窗口。但是,如果模式Dialog(由ShowDialog我的主窗口创建)处于活动状态并等待用户输入,则窗口不会关闭,因为它正在等待ShowDialog返回。如何强制模式Dialog关闭和展开代码执行?

我尝试设置DialogResultor 调用Close,但这似乎不起作用。

编辑:Dialog由我的主窗口创建,它需要一个返回值,如下所示:(在 click 事件处理程序中MainWindow):

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

当框架发送消息(来自与 UI 线程不同的线程)时,我调用MainWindow.Close(). 此时模态对话框关闭,但是检查Dialog(after ShowDialog) 的返回值的代码仍在堆栈上。不知何故,这迫使主窗口不消失。

4

3 回答 3

3

当对话框收到 WM_CLOSE 消息时,它会设置一个标志,导致 ShowDialog 在 WM_CLOSE 和任何包含消息已被完全处理后返回。因此,如果您正在Dispatcher.Invoke()对线程进行调用MainWindow.Close(),则ShowDialog()直到完成后才会返回Dispatcher.Invoke()

所以简单的解决方案是从返回Dispatcher.Invoke()得到ShowDialog()返回。如果需要更多处理,请Dispatcher.Invoke()在之后立即进行另一个处理。

如果您正在以其他方式进行线程转换Dispatcher.Invoke(),或者ShowDialog()在 Dispatcher.Invoke() 调用返回后没有返回,您可能需要发布一些围绕您的Window.Close()调用的代码,以便我们可以看到您实际在做什么.

于 2010-01-11T23:32:03.793 回答
1

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

SomeGenerator IG = Manager.SomeGenerator();
SomeWindow PP = new SomeWindow();
IG.ProgressEvent += PP.ProgressEvent;
IG.ExecuteAsync();            
PP.ShowDialog();
于 2010-01-09T02:15:36.627 回答
0

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

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

于 2010-01-12T23:15:17.187 回答