【问题标题】:Correct way to handle commands that rely on multiple view models处理依赖于多个视图模型的命令的正确方法
【发布时间】:2019-06-24 08:44:55
【问题描述】:

我对 WPF 和 MVVM 比较陌生,我正在尝试了解当命令在多个视图模型中具有依赖关系时如何正确使用它们。

几个例子:

  • 在我当前的应用程序中,我有一个 RelayCommand,它会导致在几个不同的视图模型中发生保存操作(它们编写了几个不同的文件)。目前我正在使用 mvvmlight messenger 向这些视图模型发送消息以让他们进行保存,我认为这是正确的方法,因为它避免了提供某种委托或事件到/on那些视图模型。
  • 我在一个视图模型中有一个 RelayCommand,它有一个 CanExecute 方法,该方法依赖于其他 2 个视图模型的状态。我目前也通过 mvvmlight messenger 处理了这个问题,通过更改视图模型 CanExecute 方法取决于消息,即它们的状态现在对操作有效。这看起来很混乱,但我能想到的唯一选择是使用委托或事件有效地将视图模型编织在一起,我认为我应该避免这样做。

是否有一些普遍接受的方法来处理我缺少的这个问题?

【问题讨论】:

    标签: wpf mvvm mvvm-light relaycommand routed-commands


    【解决方案1】:

    一般来说,您的视图模型层应该与您的视图具有 1:1 的关系,“保存”功能应该没有充分的理由存在于视图模型中,然后由另一个视图模型调用。

    听起来你应该做的是将该逻辑放入服务中,例如:

    public interface ISerializationService
    {
        void Save(SomeData data);
    }
    

    那么您需要一个执行实际工作的服务的实现:

    public class SerializationService : ISerializationService
    {
        void Save(SomeData data)
        {
            // actual save happens here
        }
    }
    

    您的视图模型应该包含指向这些服务实例的属性:

    public class MyViewModel : ViewModelBase
    {
        [Inject]
        public ISerializationService SerializationService { get; set; }
    
        // called when the user clicks a button or something
        private void ButtonClickCommand()
        {
            this.SerializationService.Save(this.SomeData);
        }
    }
    

    剩下的唯一问题是“什么设置了 SerializationService 的值?”,为此您需要一个依赖注入框架。那里有很多,MVVMLight 自己安装一个,但Ninject 是事实上的标准。正确实施后,注入框架将为您创建所有视图模型,然后“注入”依赖项,即 ISerializationService 类型的 SerializationService 属性,将使用您的 SerializationService 类的实例(在这样的情况也将被配置为单例)。

    依赖注入需要做一些工作才能理解,但一旦你开始使用它,你就永远不会回头。它促进了完全的关注点分离,同时减少了将指针传递到架构层次结构上下所有内容的需要。

    【讨论】:

    • 这是有道理的,我一直在手动进行依赖注入,但我真的应该看看 ninject。我没有考虑过提供储蓄服务的想法。对我来说,视图模型以处理模型对象的方式进行了保存,但我可以看到这并不完全理想。我的第二个例子呢?还是我处理的方式可以接受?谢谢!
    • 或者你看到说这两个问题真的是一样的?所以在第二种情况下,我应该将命令所依赖的视图模型的引用注入到命令所附加的视图模型中?
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2012-08-20
    • 2011-11-09
    相关资源
    最近更新 更多