2

有时视图模型需要发出通知,视图应该处理并做一些响应,尤其是。当这些不能被建模为属性和属性更改通知时。

MVVM Light 中的任何内容都可以允许视图侦听事件并通过声明性 Xaml 标记将视图模型通知转换为用户界面操作?

4

4 回答 4

3

就我个人而言,我发现从 VM 引发事件并在某些情况下在视图中捕获它们的技术是可以接受的。不过,我通常更喜欢在这种情况下使用 Messenger,尤其是在您需要自定义事件参数时(因为声明一个新的事件参数类和一个新的委托需要做很多工作)。

此外,事件处理程序是视图和视图模型之间的紧密耦合,而您通常更喜欢松耦合,但如果您知道这一事实和后果,那么为什么不...

另一种技术(例如导航、对话框等)是使用您需要的方法声明接口(例如 IDialogService 与 AskConfirmation 和 ShowMessage 方法)。然后让一个类实现该接口(可以是 MainWindow/MainPage 本身)并将其传递给 ViewModel(例如在调用 InitializeComponent 之后的 View 的构造函数中)。在 VM 中,在需要时调用这些方法。这具有很容易测试的优点(只需模拟 IDialogService 并检查方法是否被调用)。

我通常根据各种因素在 Messenger 和 IDialogService 之间移动。不过,我最近倾向于支持基于接口的方法,因为它更容易测试(但 Messenger 也很容易测试,所以 YMMV)。

干杯,劳伦特

于 2010-05-17T09:52:56.570 回答
2

在“纯”MVVM 解决方案中,唯一应该将 View 连接到 ViewModel 的是 Bindings。没有什么可以阻止您将 DataContext 转换为 ViewModel 类型并在视图中挂钩事件,但这有点违背使用 MVVM 方法的目的。作为替代方案,请尝试重新考虑为什么您认为需要向视图引发事件:

  • 需要显示弹出窗口吗?当视图模型将通知对象“插入”到绑定集合中时,可以通过适当的模板使用各种“弹出通知”绑定列表在视图上创建弹出窗口。
  • 需要强制打开下拉菜单或一些类似的 UI 操作?将 UI 上的相应属性绑定到视图模型属性,将模式设置为双向,并在视图模型上根据需要进行设置。

等等等等

于 2010-05-11T21:09:05.097 回答
1

MVVMLight 中确实有一种支持的技术,用于处理从 ViewModel 向 View 发送消息。查看 GalaSoft.MvvmLight.Messaging 命名空间内部。有一个比下面的示例发送拨号消息更好的方法,但这只是一个简单的示例。

例子

视图模型

public MainPageViewModel()
{
    Messenger.Default.Send("Payment");
}

看法

public MainPage()
{
    Messenger.Default.Register<string>(this, DialogRequested);
}

private DialogRequested(string message)
{
    MessageBox.Show(message);
}
于 2010-05-14T14:07:16.233 回答
1

您是对的,有时 ViewModel 需要与 View 进行通信。一种方法是 ViewModel 引发 View 侦听的 CLR 事件。这可以在视图的代码隐藏中完成。

MVVM 并不是要消除视图的代码隐藏!它是关于关注点分离和通过单元测试提高可测试性。

实现 ViewModel 和 View 之间通信的另一种方法是引入接口 (IView)。可以在WPF 应用程序框架 (WAF)项目站点上找到有关此方法的更多信息。

于 2010-05-14T10:25:27.313 回答