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