繁体   English   中英

在WPF MVVM中通知UserControl事件的ViewModel时的正确方法?

[英]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中的方法是创建子控件的不良方法吗? 还是我什么都不担心?

我不确定这是否对您有用,只是我的想法。

如果您有一个MainViewModel可以容纳所有其他ViewModels如上图所示),则可以公开Properties/Methods来调用MainViewModel,然后让MainViewModel决定与其他ViewModel进行对话。

我个人更喜欢用依赖注入来实现这样的事情。 通常,需要发出多个通知,因此首先声明一个接口:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM