代码之家  ›  专栏  ›  技术社区  ›  Guy

模拟ShowDialog功能

  •  5
  • Guy  · 技术社区  · 15 年前

    我正在编写一个应用程序(c#+wpf),其中所有模态风格的对话框都作为 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); 
    

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

    base.ShowMessageBox 直到对话框关闭事件被它引发,但是我看不出如果不挂起GUI线程,从而阻止用户单击OK,怎么可能等待它。我知道我可以将委托函数作为 ShowMessageBox 函数可以防止执行反转,但仍然会导致一些疯狂的语法/缩进。

    4 回复  |  直到 13 年前
        1
  •  5
  •   Chris Shouts    15 年前

    你可能想看看 this 关于CodeProject和 this 关于MSDN的文章。第一篇文章指导您手动创建一个阻塞模式对话框,第二篇文章演示如何创建自定义对话框。

        2
  •  5
  •   Cameron MacFarland    9 年前

    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
  •  0
  •   SLaks    15 年前

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

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

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

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

        4
  •  0
  •   Mongus Pong    15 年前

    在MessageBox类中设置另一个消息循环。比如:

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