有时视图模型需要发出通知,视图应该处理并做一些响应,尤其是。当这些不能被建模为属性和属性更改通知时。
MVVM Light 中的任何内容都可以允许视图侦听事件并通过声明性 Xaml 标记将视图模型通知转换为用户界面操作?
有时视图模型需要发出通知,视图应该处理并做一些响应,尤其是。当这些不能被建模为属性和属性更改通知时。
MVVM Light 中的任何内容都可以允许视图侦听事件并通过声明性 Xaml 标记将视图模型通知转换为用户界面操作?
就我个人而言,我发现从 VM 引发事件并在某些情况下在视图中捕获它们的技术是可以接受的。不过,我通常更喜欢在这种情况下使用 Messenger,尤其是在您需要自定义事件参数时(因为声明一个新的事件参数类和一个新的委托需要做很多工作)。
此外,事件处理程序是视图和视图模型之间的紧密耦合,而您通常更喜欢松耦合,但如果您知道这一事实和后果,那么为什么不...
另一种技术(例如导航、对话框等)是使用您需要的方法声明接口(例如 IDialogService 与 AskConfirmation 和 ShowMessage 方法)。然后让一个类实现该接口(可以是 MainWindow/MainPage 本身)并将其传递给 ViewModel(例如在调用 InitializeComponent 之后的 View 的构造函数中)。在 VM 中,在需要时调用这些方法。这具有很容易测试的优点(只需模拟 IDialogService 并检查方法是否被调用)。
我通常根据各种因素在 Messenger 和 IDialogService 之间移动。不过,我最近倾向于支持基于接口的方法,因为它更容易测试(但 Messenger 也很容易测试,所以 YMMV)。
干杯,劳伦特
在“纯”MVVM 解决方案中,唯一应该将 View 连接到 ViewModel 的是 Bindings。没有什么可以阻止您将 DataContext 转换为 ViewModel 类型并在视图中挂钩事件,但这有点违背使用 MVVM 方法的目的。作为替代方案,请尝试重新考虑为什么您认为需要向视图引发事件:
等等等等
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);
}
您是对的,有时 ViewModel 需要与 View 进行通信。一种方法是 ViewModel 引发 View 侦听的 CLR 事件。这可以在视图的代码隐藏中完成。
MVVM 并不是要消除视图的代码隐藏!它是关于关注点分离和通过单元测试提高可测试性。
实现 ViewModel 和 View 之间通信的另一种方法是引入接口 (IView)。可以在WPF 应用程序框架 (WAF)项目站点上找到有关此方法的更多信息。