【问题标题】:Error window show modal in MVVM WPF错误窗口在 MVVM WPF 中显示模式
【发布时间】:2009-08-24 09:28:03
【问题描述】:

我已将我的 MVVM 错误消息实现为一个消息对话框,该对话框通过中介类订阅错误消息,以便其他视图模型可以在发生任何错误时通知它。

当发生错误时,我将 viewmodel 中的可见性属性设置为 Visible,以显示错误窗口。这一切都绑定在视图模型的错误窗口中。

但是,这个窗口不是模态的!我需要将其显示为对话框,而不仅仅是将可见性设置为 true - 即使我必须扩展窗口的功能,我可以做任何类型的绑定吗?如果可以避免,我宁愿不破坏 MVVM。

谢谢!

【问题讨论】:

  • 也许在错误窗口的代码隐藏中覆盖一些 OnvisibilityChanged 处理程序?

标签: wpf mvvm modal-dialog


【解决方案1】:

View/ViewModel 拆分旨在将外观与功能分开。我坚信 Window 是功能性的,并且看起来合二为一。例如,如果在您的 ErrorMessageViewModel 中,当出现错误时,您会执行以下代码:

class WindowViewModel : Window
{
}

.
.
.

WindowViewModel newDialog = new WindowViewModel();
newDialog.Content = myErrorListViewModel;
newDialog.Parent = mainWindowViewModel;
newDialog.ShowDialog();

所以对话框的内容就是你的错误列表的 ViewModel。将您的 View 定义为一个数据模板,它会自动将自身应用于错误列表 ViewModel。

这看起来不像 MVVM 吗?

事实上,Window 类是您在屏幕上看到的 Window 的 ViewModel。通过更改 Window 对象的属性,它会影响“视图”,就像 WindowView 的属性绑定到 WindowViewModel 一样。唯一缺少的是使用 WPF“重新设计”窗口的能力,无论你多么努力地实现它,你都无法做到这一点。用户可以通过修改其桌面主题来重新设置 Window 的样式,但您无法控制它。您能做的最好的事情就是关闭 chrome 和/或使其全屏显示。

【讨论】:

  • @russau:人们会假设微软已经对 Window 类本身进行了合理的单元测试。您当然可以编写单元测试来执行您在 WindowViewModel 类本身中编写的任何附加功能。
【解决方案2】:

您可以在此项目的 ViewModel 示例中找到如何显示窗口(无论它们是否为模态)的示例:

WPF 应用程序框架 (WAF)

http://waf.codeplex.com

【讨论】:

    【解决方案3】:

    我也在做一个 MVVM 项目,我需要模态对话框或消息框。我找到了以下解决方法:

    该软件只使用一个窗口。布局根元素是一个没有行或列定义的 Grid。网格有三个孩子:

    1. 包含所有常用内容的停靠面板,如菜单、选项卡式视图、状态栏等。
    2. 具有灰色背景和 50% 不透明度的网格。当模态框生效时,这用作遮盖停靠面板的面纱。面纱网格通常是折叠的。
    3. 包含模态视图的网格,通常是折叠的。

    主窗口的视图模型有一个名为 Modal 的成员。如果为 null,则用于模式使用的两个网格通过数据绑定和 Visibility.Collapsed 的转换器折叠。

    例如,当程序想要显示模式消息框时,MessageBoxViewModel 被实例化并分配给 MainViewModel.Modal。 MessageBoxViewModel 有一个用于确定按钮的命令。此命令引发一个将 MainViewModel.Modal 再次设置为 null 的事件。

    面纱网格遮挡了主 DockPanel,因此 Modal 控件之外的控件均不接受输入。

    您的程序可以运行 messagepump 直到按下 OK,或者 OK-Command 可以触发下一个。有很多方法可以解决不同的需求,但 Model-ModelView 解决方案应该支持它们。

    我觉得这是模态模式下的视图模型,这是人们所希望的。

    【讨论】:

      【解决方案4】:

      我做了一个行为来将一些模式对话框与命令联系起来。

      http://www.clr-namespace.com/post/MVVMModal-dialog-before-running-Command.aspx

      <Confirm:Confirm IsConfirm="{Binding ElementName=checkBoxConfirm, Path=IsChecked}"
      Command="{Binding Path=ButtonCommand}" 
      CommandParameter="{Binding ElementName=textBoxParameter, Path=Text}" 
      ConfirmMessage="Are you sure you want to fire the command?" 
      ConfirmCaption="Question" >
      </Confirm:Confirm>
      

      【讨论】:

        【解决方案5】:

        在我最近的博客文章中,您可以找到适用于 Silverlight 的 MVVM 中的模态对话框和消息框的简单解决方案,但这可以在 WPF 中简单地重用:

        Modal dialogs with MVVM and Silverlight 4

        【讨论】:

        • 我已经对你的文章发表了评论,第二天还在等待审核。因此,我将在这里重复我的答案:“您断言,这是一个与平台无关的决定,但据我所知,WPF 窗口具有用于将自身显示为模态对话框的方法 ShowDialog。当您使用通常的 Show 方法时。这不会导致模态行为,对吗?”
        【解决方案6】:

        我使用与 Scott Whitlock 相同的方法。

        只需要设置一个更重要的属性:

        class ModalDialog: Window
        {
        }
        
        .
        .
        .
        
        var dlg = new ModalDialog {
            Content = viewModelName,
            **TopMost = true,**
            Parent = mainWindowViewModel
        };
        
        dlg.ShowDialog();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-19
          • 1970-01-01
          相关资源
          最近更新 更多