【问题标题】:Showing a message box from the ViewModel is a violation of MVVM - how to avoid?从 ViewModel 显示消息框违反了 MVVM - 如何避免?
【发布时间】:2013-06-01 21:57:25
【问题描述】:

在 Pluralsight 上观看有关 MVVM 的视频时,出现了违反 MVVM 模式但没有显示正确方法的情况:

  • 视图有一个按钮,该按钮使用 ICommand 触发 ViewModel 中的处理程序。
  • 处理程序正确地将执行中继到存储库实现。
  • 存储库的具体实现称为 Web 服务方法。

但是:如果 web 服务调用失败,ViewModel 会弹出一个消息框,通知用户该错误。 由于 ViewModel 是 View 的抽象,它不应该直接创建 UI,但是将消息框呈现给用户的 100% 干净的方法是什么?

【问题讨论】:

    标签: c# mvvm


    【解决方案1】:

    创建服务:

    interface IDialogService
    {
        void ShowMessageBox(string message);
    }
    

    实现它:

    class DialogService : IDialogService
    {
        public void ShowMessageBox(string message)
        {
            MessageBox.Show(); // ...
        }
    }
    

    使用依赖注入:

    class ViewModel
    {
        [Import] // This is MEF-specific sample
        private readonly IDialogService dialogService;
    }
    

    或服务地点:

    class ViewModel
    {
        private AnyCommandExecute()
        {   
            // This is MEF-specific sample
            var dialogService = container.GetExportedValue<IDialogService>();
        }
    }
    

    在你的视图模型中获得一个具体的IDialogService,然后从ViewModel中调用获得的实现。

    同样的方法适用于任何其他类似情况:显示打开/保存对话框,在对话框中显示您的自定义视图模型。

    【讨论】:

    • 看起来简单而有意义。但是,如果我通过不实现 ShowMessageBox() 来创建 ViewModel 抽象,并且有一个用于单元测试的实现和一个用于生产使用的实现,那么在没有依赖注入的情况下我最终会得到相同的效果。对这种方法有什么意见或批评吗?
    • 1) 这违反了 SRP。您正在让视图模型负责一切。 2)您应该保留每个视图模型的 2 个实现,而不是 2 个服务实现(一个用于生产,一个用于测试),这需要此功能。 3)考虑一下:SomeViewModel需要显示消息框,它有抽象ShowMessageBoxSomeDerivedViewModel : SomeViewModel 不需要显示,但是你已经有了这个方法。
    【解决方案2】:

    有几种方法可以遵循 MVVM 模式,例如 Interaction ServiceInteraction Request

    交互服务

    ...视图模型可以用来启动交互的服务 与用户,从而保持其对视图的独立性 实施

    交互请求

    ... 使用视图模型引发的事件来表达意图 与用户交互,以及视图中的组件 绑定到这些事件,并管理的视觉方面 互动。

    来源

    以上两个引用均来自此来源(其中还包含有关模式的更多详细信息):http://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx#sec10

    【讨论】:

      猜你喜欢
      • 2015-05-19
      • 2011-04-11
      • 1970-01-01
      • 2010-12-31
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多