C# 如何重现Window.ShowDialog()的行为

C# 如何重现Window.ShowDialog()的行为,c#,wpf,dispatcher,event-loop,C#,Wpf,Dispatcher,Event Loop,短版本:如何在特定堆栈帧上泵送消息,以便在阻塞时可以等待自定义对话框返回,就像Window.ShowDialog()一样。理想情况下避免异步或多线程 我正在为我的应用程序创建一个自定义通知对话框,它支持一组不同的显示模式 通过使用Window.ShowDialog(),它可以用作阻止弹出窗口,与MessageBox.Show完全相同。通过使用常规的Show命令,它还可以充当非阻塞消息框 但是,我希望使用第三种模式,在这种模式下,对话框可以通过非阻塞调用显示,但是稍后另一个调用将阻塞,直到用户关闭

短版本:如何在特定堆栈帧上泵送消息,以便在阻塞时可以等待自定义对话框返回,就像Window.ShowDialog()一样。理想情况下避免异步或多线程

我正在为我的应用程序创建一个自定义通知对话框,它支持一组不同的显示模式

通过使用Window.ShowDialog(),它可以用作阻止弹出窗口,与MessageBox.Show完全相同。通过使用常规的Show命令,它还可以充当非阻塞消息框

但是,我希望使用第三种模式,在这种模式下,对话框可以通过非阻塞调用显示,但是稍后另一个调用将阻塞,直到用户关闭对话框。这样我就可以让用户更早地知道他们什么时候需要做一些事情,但是当时间到了,如果用户还没有取消它,主应用程序线程就会阻塞

请记住,我并没有在这方面使用Async

基本上: NotifyDialog.ShowNonBlocking(“请删除设备并单击确定”); //做一些事情,等待处理完成

//现在处理完成了,我们真的需要在下一件事情开始之前清除设备。 NotifyDialog.blockUntlClosed()//禁用主窗口,在此处启动嵌套消息泵

我首先错误地认为创建一个新窗口会自动创建一个新线程和调度程序队列,所以我尝试使用一个条件。结果表明,它不会创建新线程。我假设这是因为Window.ShowDialog()在显示新对话框时被阻塞,但就我现在所知,它只是禁用了所有其他窗口,并劫持了消息泵(我假设堆栈看起来像main->message pump->event,将我们引导到ShowDialog()调用->new,hijacked message pump循环)

无论如何,我希望手动复制此行为,以便在NotifyDialog.blockUntlClosed()调用中,我可以劫持消息泵,禁用主窗口,然后等待窗口关闭

如果这是不可能的,我会回到一个新的线程上启动窗口的计划,这似乎有一些文章解释


我想让它易于使用,所以我不想依赖于使用者需要使用的关闭事件回调,而且我的应用程序现在没有使用异步,所以我不能等待结果。

好的,解决它

调度程序有一个名为PushFrame的方法。此函数是一个简单的事件循环。它是一个while循环,在传入的DispatcherFrame上的continue标志设置为false之前不会返回,此时它停止处理事件并返回

解决方案是在我的类中添加一个成员Dispatcher框架,并在调用BlockUntilClosed方法时构造它并通过PushFrame调用将其传递给Dispatcher。然后,在对话框的关闭事件处理程序中,我将continue标志设置为false。Dispatcher完成关闭事件的处理后,会检测到continue标志已清除并返回

这里有一个相当好的描述:


看起来你并不是在问一个特定的问题,而是在要求别人给你一些代码,这些代码可以实现你所描述的。因此,这不适合stackoverflow的问答格式。谢谢John。看起来我的问题的答案在DispatcherFrame类中;ShowDialog()是一个非常不受欢迎的方法调用,它覆盖了巨大的表面积。众所周知,人们对再进入的问题知之甚少。你自己承担风险,援引事件的危险作为背景信息。嗨,扎克,谢谢你的反馈。我想我的问题是,是否可以与调度员一起执行X是一个明确的问题。X的定义明确、具体且范围有限。我已经尽力排除了其他的解决方案。