我有一个管理客户和地址的经典商业应用程序。
每个自己的ViewModel都有标签项(Id,GenericInfo和更多)。
有一个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中注册该容器,然后viewmodel用它拥有的数据(用户)填充它。
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的正确方法吗?你会改进什么?
答案 0 :(得分:2)
没有正确的方式来使用信使。但是,您必须考虑该消息由已注册该消息的所有收件人处理,而不仅仅是预期的子集。此外,在使用消息传递时,您无法控制消息处理何时完成,现在,当所有收件人完成处理消息时,您会收到通知。另外 - 根据信使的实现 - 消息可以并行处理。
因此,您的方法(以及使用回调的@cadrell0扩展)的问题在于您不知道所有收件人何时处理了该消息。使用回调,您将获得处理邮件的每个收件人的回调(即n个收件人n回调)。
那么如何检查所有收件人何时完成处理邮件?
正如我所看到的,消息传递更多地被设计为通知机制,即您通知某些收件人发生了某些事情。如果您知道并且可以确保只有一个收件人,您甚至可以按照您描述的方式使用它,但只要涉及多个收件人,就会导致上述问题。
那么这会让你离开...在你的szenario我倾向于将视图模型设计为“相关”(即主视图模型知道关于用户视图模型和< / strong>地址视图模型 - 或主视图模型知道关于用户视图模型,如果更合适,则知道关于地址视图模型。通常,我也会设计一个包含我必须处理的工作单元的模型(在你的情况下是SaveContainer)。然后,从该模型构造所有视图模型并将其数据写入其中。在正常情况下,这个工作单元是您从数据存储服务获得的,而这又是由数据存储在单个事务中保存的。
但同样,MVVM没有正确的方式!
答案 1 :(得分:0)
如果我需要在收件人回复邮件后做某事我在邮件中加入回调。收件人完成后,它会执行回调。向回调添加参数允许收件人将数据发送给发件人。这也允许收件人执行异步操作。