【问题标题】:Emulating ShowDialog functionality模拟 ShowDialog 功能
【发布时间】:2009-12-01 15:05:00
【问题描述】:

我正在编写一个应用程序 (c# + wpf),其中所有模式样式对话框都实现为覆盖主要 Window 的半透明网格顶部的 UserControl。这意味着只有一个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线程的情况下等待这个,从而防止用户曾经单击确定。我知道我可以将委托函数作为 ShowMessageBox 函数的参数,这可以防止执行反转,但仍然会导致一些疯狂的语法/缩进。

我是否遗漏了一些明显的东西,或者是否有标准的方法来做到这一点?

【问题讨论】:

    标签: c# wpf events dialog messagebox


    【解决方案1】:

    您可能想查看 CodeProject 上的 this 文章和 MSDN 上的 this 文章。第一篇文章引导您手动创建阻塞模式对话框,第二篇文章说明如何创建自定义对话框。

    【讨论】:

    • 链接的第一篇文章展示了如何做到这一点的完美示例。
    【解决方案2】:

    执行此操作的方法是使用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);
    

    【讨论】:

      【解决方案3】:

      你可以把你的函数变成一个返回IEnumerator<CustomMessageBox>的迭代器,然后这样写:

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

      然后,您将编写一个包装函数,该函数接受枚举器并在 DialogClosed 处理程序中调用 MoveNext(它将执行所有函数,直到下一个 yield return)。

      请注意,包装函数不会是阻塞调用。

      【讨论】:

        【解决方案4】:

        在消息框类中设置另一个消息循环。类似的东西:

        public DialogResult ShowModal()
        {
          this.Show();
        
          while (!this.isDisposed)
          {
            Application.DoEvents();
          } 
        
           return dialogResult;
        }
        

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

        【讨论】:

        • 他使用的是 WPF,而不是 WinForms。
        • 啊,我错过了。 WPF完全不同? windows不再有消息循环了吗?
        猜你喜欢
        • 1970-01-01
        • 2018-09-20
        • 1970-01-01
        • 2020-06-19
        • 2019-07-16
        • 2015-10-21
        • 2012-08-16
        • 2021-04-29
        • 1970-01-01
        相关资源
        最近更新 更多