从ViewModel到View的通知

时间:2016-11-01 08:07:10

标签: wpf mvvm

我需要从ViewModel向MVVM WPF应用程序中的View发送通知。在大多数情况下,它将是View端的简单MessageBox。在ViewModel中使用类似System.Windows.MessageBoxResult或System.Windows.MessageBoxImage的类型是不可接受的违反MVVM模式的(在这种情况下,VM必须引用特定于UI的库)?

我需要从VM传递标题,消息和通知类型,并且通过创建自定义枚举,我实际上是从.NET Framework复制现有功能。

3 个答案:

答案 0 :(得分:1)

您不需要通知机制。这是一个选择。另一个是使用简单的服务类:

public class ViewModel
{
    IDialogService _dialogService; //ctor injection or use service locator

    public void CommandExecute()
    {
        _dialogService.ShowMessageBox(...);
    }
}

public interface IDialogService
{
    bool? ShowMessageBox(params....);
}

public class DialogService : IDialogService
{
    public bool? ShowDialog(params...)
    {
        MessageBox.Show(params...);
    }
}

我觉得这种方法更直接,更容易理解,更容易调试。消息传递可能很容易变成内存泄漏,在这种情况下,我认为我的方法没有任何好处。

修改

  

您是否会在ShowMessageBox参数中使用自定义枚举,或者您将使用   System.Windows.MessageBoxImage?

首先,ViewModel属于表示层。可以在ViewModel中使用System.Windows.MessageBoxImage之类的枚举。 在MVVM中,由于以下原因,ViewModel与Views分离:

  • ViewModels以可轻易从Views(例如DataBinding)消费的方式公开Model中的数据和逻辑
  • ViewModels更易于测试
  • ViewModels提供更好的设计时支持(可混合性,测试数据)
  • ViewModels将应用程序逻辑与实际的表示标记分开,使其更易于理解(可读性)

使用System.Windows.MessageBoxImage之类的枚举会破坏上述任何一点吗?答案是不。

如果您想在多个平台上重用IDialogService和ViewModel,例如WPF,UWP和Xamarin,那么您需要创建自己的枚举,因为它可能不存在于所有平台上。黄金法则是:如果您不需要,请不要添加另一层抽象。

答案 1 :(得分:0)

您可以让视图实现一个接口,比如INotificationService,然后将视图传递给视图模型构造函数。这不会违反MVVM,您仍然可以使用视图上的DataContext属性将视图模型绑定到视图。

答案 2 :(得分:-1)

我决定将ViewModel保持为尽可能清晰的UI(View)内容,因此我将创建受MessageBox启发的自定义枚举,并根据我的需求进行定制。