处理依赖于多个视图模型的命令的正确方法
Correct way to handle commands that rely on multiple view models
我对 WPF 和 MVVM 比较陌生,我正在尝试了解当它们在多个视图模型中具有依赖项时如何正确使用命令。
举几个例子:
- 在我当前的应用程序中,我有一个 RelayCommand,它会导致在几个不同的视图模型(它们写入几个不同的文件)中发生保存操作。目前我正在使用 mvvmlight 信使向这些视图模型发送消息以让它们进行保存,我认为这是正确的方法,因为它避免了必须提供某种委托或事件 to/on 那些视图模型。
- 我在视图模型中有一个 RelayCommand,它有一个 CanExecute 方法,该方法依赖于其他 2 个视图模型的状态。我目前已经通过 mvvmlight 信使以及更改视图模型来处理此问题,CanExecute 方法取决于它们的状态现在对操作有效的消息。这看起来很混乱,但我能想到的唯一选择是使用委托或事件有效地将视图模型编织在一起,我认为我应该避免这种情况。
是否有一些普遍接受的方法来处理我所缺少的这个问题?
一般来说,你的视图模型层应该与你的视图有 1:1 关系,"Save" 函数应该没有充分的理由存在于视图模型中,然后由另一个视图模型调用查看模型。
听起来您应该做的是将该逻辑放入服务中,即类似这样的事情:
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);
}
}
剩下的唯一问题是 "What sets the value of SerializationService?",为此您需要一个依赖注入框架。那里有很多,MVVMLight 自己安装一个,但 Ninject 是事实上的标准。正确实施后,注入框架将为您创建所有视图模型,然后 "inject" 依赖项,即类型为 ISerializationService
的 SerializationService
属性,将使用实例进行初始化您的 SerializationService
class(在这种情况下也将配置为单例)。
依赖注入需要一些工作来让你的头脑清醒,但一旦你开始使用它,你将永远不会回头。它促进了完全的关注点分离,同时减少了将指针传递给架构层次结构上下所有内容的需要。
我对 WPF 和 MVVM 比较陌生,我正在尝试了解当它们在多个视图模型中具有依赖项时如何正确使用命令。
举几个例子:
- 在我当前的应用程序中,我有一个 RelayCommand,它会导致在几个不同的视图模型(它们写入几个不同的文件)中发生保存操作。目前我正在使用 mvvmlight 信使向这些视图模型发送消息以让它们进行保存,我认为这是正确的方法,因为它避免了必须提供某种委托或事件 to/on 那些视图模型。
- 我在视图模型中有一个 RelayCommand,它有一个 CanExecute 方法,该方法依赖于其他 2 个视图模型的状态。我目前已经通过 mvvmlight 信使以及更改视图模型来处理此问题,CanExecute 方法取决于它们的状态现在对操作有效的消息。这看起来很混乱,但我能想到的唯一选择是使用委托或事件有效地将视图模型编织在一起,我认为我应该避免这种情况。
是否有一些普遍接受的方法来处理我所缺少的这个问题?
一般来说,你的视图模型层应该与你的视图有 1:1 关系,"Save" 函数应该没有充分的理由存在于视图模型中,然后由另一个视图模型调用查看模型。
听起来您应该做的是将该逻辑放入服务中,即类似这样的事情:
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);
}
}
剩下的唯一问题是 "What sets the value of SerializationService?",为此您需要一个依赖注入框架。那里有很多,MVVMLight 自己安装一个,但 Ninject 是事实上的标准。正确实施后,注入框架将为您创建所有视图模型,然后 "inject" 依赖项,即类型为 ISerializationService
的 SerializationService
属性,将使用实例进行初始化您的 SerializationService
class(在这种情况下也将配置为单例)。
依赖注入需要一些工作来让你的头脑清醒,但一旦你开始使用它,你将永远不会回头。它促进了完全的关注点分离,同时减少了将指针传递给架构层次结构上下所有内容的需要。