[英]MVVMLight : is this the right way to use the Messenger?
我有一个管理客户和地址的经典业务应用程序。
有选项卡项(Id、GenericInfo 等),每个项都有自己的 ViewModel。
有一个 MainViewModel 处理客户端及其地址的保存和加载命令。
我们从 WCF 服务中检索数据。 从每个 WCF 函数接收/发送的数据聚合在不同的容器中。
在我的 MainViewModel 中,我创建了一个 SaveContainer,然后将它与 Messenger 一起发送。
public void Save()
{
var container = new SaveContainer();
MessengerInstance.Send(container);
//the container is now populated and ready to be sent via WCF
Console.WriteLine(container.User.Name);
Console.WriteLine(container.Address.StreetName);
Console.WriteLine(container.Address2.StreetName);
}
在我的 UserViewModel 中注册了该容器,然后视图模型用它拥有的数据(用户)填充它。
public UserViewModel()
: base(Messenger.Default)
{
User = new User();
MessengerInstance.Register<SaveContainer>(this, (x) => x.User = User);
}
在我的 AddressViewModel 中,我也这样做。
public AddressViewModel()
: base(Messenger.Default)
{
Address = new Address();
Address2 = new Address() { StreetName = "Washington Street" };
MessengerInstance.Register<SaveContainer>(this, x =>
{
x.Address = Address;
x.Address2 = Address2;
});
}
当我必须加载数据时,我也会这样做。
在我发送消息后,我假设每个注册的 ViewModel 都收到了消息并处理了它。 我假设错了吗? 您认为这种方式是使用 Messenger 的正确方式吗? 你会改进什么?
没有使用信使的正确方法。 但是,您必须考虑到该消息由所有注册该消息的收件人处理,而不仅仅是预期的子集。 此外,在使用消息传递时,您无法控制消息处理何时完成,现在您是否会在所有收件人处理完消息时收到通知。 此外 - 取决于信使的实现 - 可以并行处理消息。
因此,您的方法(以及@cadrell0 使用回调的扩展名)的问题在于您不知道所有收件人何时都处理了消息。 使用回调,您将获得处理消息的每个接收者的回调(即 n 个接收者 n 个回调)。
那么如何检查所有收件人何时处理完邮件?
在我看来,消息传递更像是一种通知机制,即您通知某些收件人发生了某些事情。 如果您知道并且可以确保只有一个收件人,您甚至可以按照您描述的方式使用它,但是一旦涉及多个收件人,就会导致上述问题。
那么这会让你在哪里......在你的szenario中我倾向于将视图模型设计为“相关”(即主视图模型知道用户视图模型和地址视图模型 - 或者主视图模型知道用户如果更合适的话,视图模型又知道地址视图模型)。 通常,我还会设计一个模型来保存我必须处理的工作单元(在您的情况下是 SaveContainer)。 然后所有的视图模型都是从这个模型构建的,并将它们的数据写入其中。 在正常情况下,此工作单元是您从数据存储服务中获得的内容,而数据存储又会在单个事务中保存这些内容。
但同样,MVVM 没有正确的方法!
如果我需要在收件人回复消息后做某事,我会在我的消息中包含回调。 当接收者完成时,它执行回调。 向回调添加参数允许接收者向发送者发送数据。 这也允许接收者执行异步操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.