[英]Correct approach when notifying ViewModels of UserControl events in WPF MVVM?
在WPF视图中,我将数据加载到用户控件中,如下所示:
<ContentControl Content="{Binding ItemEditVm}" />
然后在ViewModel中:
private ItemEditViewModel _itemEditVm;
public ItemEditViewModel ItemEditVm
{
get
{
return _itemEditVm;
}
set
{
_itemEditVm = value;
OnPropertyChanged("ItemEditVm");
}
}
我有一系列的DataTemplates来说明哪个View属于哪个ViewModel。 然后,在我的业务逻辑中,我可以为UserControl旋转一个新的ViewModel,然后将其分配给该属性,并按预期进行所有工作。
但是,要解决此应用程序中的下一个任务,我需要能够将UserControl内部发生的事件通知给父ViewModel。 我在子ViewModel上有一个简单事件,在父类上有一个侦听器来完成此操作:
public event EventHandler ItemEditViewModelChanged();
因此,当我创建ViewModel时,我可以仅添加一个侦听器:
ItemEditViewModel vm = new ItemEditViewModel(itemId);
vm.ItemEditViewModelChanged += vm_ItemEditViewModelChanged;
并在vm_ItemEditViewModelChanged()中执行所需的操作。
但是,我本能地对此感到不舒服。 尽管它没有违反任何MVVM原理的要求(事物仍然是可测试的,视图和ViewModels仍然是分开的),但它似乎不是一种非常灵活的处理方式,并且确实在ViewModel类之间创建了不良的逻辑链接。
有更好的方法吗? 我创建UserControls并将其加载到ContentControls中的方法是创建子控件的不良方法吗? 还是我什么都不担心?
我个人更喜欢用依赖注入来实现这样的事情。 通常,需要发出多个通知,因此首先声明一个接口:
public interface ICustomEventHandler
{
void Event1();
void Event2();
// .. etc
}
然后在子虚拟机中,使用依赖项注入来注入需要监视它的任何对象:
public class ChildVM
{
[Inject] public ICustomEventHandler Watcher {get; set;}
// .. etc ..
}
首先,这使模拟变得非常容易,因此涵盖了单元测试,但是更重要的是,您已经正式定义了该模块与其余代码之间的依赖关系,并且还保留了如何最佳实施的选项。 (一种简单的解决方案是让父级直接实现该接口,并在创建时将其自身注入子级,在另一种情况下,您可能需要使用具有单例作用域或多个客户端的中间类)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.