2015-07-20 30 views
0

想象一下,带有一个主视图的WPF应用程序代表一个可以多次打开的窗口。这个主视图有几个孩子的意见。MVVMLight使者是否有范围?

使者可以在主视图及其子视图的视图模型的视图模型之间发送消息。

是否可以使信使受限制的范围,以便如果您有两个主要视图打开,与其交互只会消息该视图的子视图?

是否有另一种方式来以尊重MVVM的方式在父视图模型和子视图模型之间共享“标识”?

回答

1

您可以随时通过默认IMessenger这将有静态,应用领域范围或信使创建新实例之间进行选择:

var domainWideMessenger = GalaSoft.MvvmLight.Messaging.Messenger.Default; 
var localMessenger = new Messenger(); 

第一种方法是,当你不想控制的范围有用信使。你可以把它当作一个中心枢纽。 “本地”信使适用于虚拟机内或某个容器内的通信。

为什么这可能会更好,然后有令牌?当您在某些时候使用基于令牌的消息进行高级应用程序时,您会遇到困难(选择正确的应用程序)。特别是当涉及依赖注入时。

在您的情况下,您将拥有的新实例/ MainView,该实例将被推送到其所有子视图和查看模型。要同步数据并在MainView的多个实例之间进行通信,请使用MVVM Light的静态Messenger

+0

问题确实存在。这不仅仅是让信使进入,而是确保DI能够智能地完成任务。所以我仍然需要考虑一个方案来让DI创建/选择正确的使者。 – Ian

1

您可以使用“令牌”的概念来实现此效果。

IMessenger接口有过载RegisterSend接受一个对象来限制哪些注册者接收消息。如果消息是使用令牌发送的,那么将看到消息的唯一对象是那些使用相同标记注册该消息的对象。在这里,“same”意味着对象相等,所以你可以使用任何具有明智的相等语义并且对你有意义的标记的对象,即GUID,整数或字符串。

作为一个例子,考虑下列对象:

public static class MessengerHelper 
{ 
    public static IMessenger Messenger { get { return GalaSoft.MvvmLight.Messaging.Messenger.Default; } } 
    public static object Group1Token { get { return 1; } } 
    public static object Group2Token { get { return 2; } } 
} 

public class FooChild 
{ 
    object token; 

    public FooChild(object token) 
    { 
     this.token = token; 
     MessengerHelper.Messenger.Register<IFooMessage>(this, token, HandleFooMessage); 
    } 

    void HandleFooMessage(IFooMessage fooMessage) 
    { 
     Console.WriteLine("FooChild got the message, token = " + (token ?? "(null)")); 
    } 
} 

public class FooParent 
{ 
    FooChild[] children; 

    public FooParent() 
    { 
     children = new [] { 
      new FooChild(MessengerHelper.Group1Token), 
      new FooChild(MessengerHelper.Group2Token), 
      new FooChild(null) 
     }; 
    } 

    public void SendFooMessage(IFooMessage fooMessage, object token) 
    { 
     MessengerHelper.Messenger.Send(fooMessage, token); 
    } 
} 

然后,如果你创建父和给定的令牌发送消息:

FooParent parent = new FooParent(); 
parent.SendFooMessage(new FooMessage(), MessengerHelper.Group1Token); 
parent.SendFooMessage(new FooMessage(), MessengerHelper.Group2Token); 

你会得到下面的输出:

FooChild得到的消息,标记= 1

FooChild得到的消息,令牌= 2

在你的情况,你会希望每个主视图模型有自己的道理,并通过他们的礼物给他们的孩子视图模型。

+0

你的回答比我的问题要好:)为了保持简单,我省略了DI方面。所以这种方法出色,但我的DI不能自动选择正确的令牌。 – Ian

+1

对于DI部件,您可以定义一个工厂来创建您的子视图模型。参见[Castle Windsor's](https://github.com/castleproject/Windsor/blob/master/docs/typed-factory-facility-interface-based.md)实现。 –

相关问题