模拟ShowDialog功能

5

我是一名应用程序开发者(使用c# + wpf),在我的应用程序中,所有的模态样式对话框都是以 UserControl 的形式实现的,覆盖在主 Window 上方的半透明网格中。这意味着只有一个 Window,并且它保持了所有公司应用程序的外观和感觉。

要显示一个 MessageBox,语法如下:

CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
   // the rest of the function
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b); 

正如您所看到的,执行流程不仅被倒置了,而且与经典的.NET版本相比,它非常冗长。

MessageBox.Show("hello world");
// the rest of the function

我真正需要的是一种方法,能够在对话框关闭事件被触发之前,不从base.ShowMessageBox返回,但我无法想象如何等待它而不会挂起GUI线程,从而阻止用户单击OK。我知道可以将委托函数作为ShowMessageBox函数的参数,这可以防止执行的倒置,但仍会导致一些疯狂的语法/缩进问题。
我是否遗漏了某些明显的事情?或者有没有标准的方法可以做到这一点?
4个回答

5
使用一个DispatcherFrame对象来实现这一点。该对象的使用方式请参考DispatcherFrame文档
var frame = new DispatcherFrame();
CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
    frame.Continue = false; // stops the frame
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b);

// This will "block" execution of the current dispatcher frame
// and run our frame until the dialog is closed.
Dispatcher.PushFrame(frame);

5

您可能需要查看CodeProject上的这篇文章和MSDN上的这篇文章。第一篇文章指导您手动创建一个阻塞模态对话框,而第二篇文章说明了如何创建自定义对话框。


第一篇链接的文章展示了如何完美地做到这一点的完美例子。 - Guy

1
在消息框类中设置另一个消息循环。类似这样的代码:
public DialogResult ShowModal()
{
  this.Show();

  while (!this.isDisposed)
  {
    Application.DoEvents();
  } 

   return dialogResult;
}

如果你在Reflector中查看Windows.Form,你会发现它做了类似于这样的事情...


他正在使用WPF,而不是WinForms。 - SLaks
啊,我错过了。WPF完全不同了吗?Windows不再有消息循环了吗? - Mongus Pong
不要使用以下解决方案:while (!this.isDisposed) { Application.DoEvents(); }它会阻塞UI或通过DoEvents耗尽UI。 - bmi

0
你可以将你的函数改写为一个返回 IEnumerator<CustomMessageBox> 的迭代器,然后像这样编写它:

//some code
yield return new CustomMessageBox("hello world");
//some more code

你需要编写一个包装函数,该函数接受枚举器并调用 MoveNext(这将执行所有函数,直到下一个 yield return)在 DialogClosed 处理程序中。
请注意,包装函数不会阻塞调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接