繁体   English   中英

MVVMLight Messenger有范围吗?

[英]Does the MVVMLight messenger have scope?

想象一个WPF应用程序,其中一个主视图代表一个可以多次打开的窗口。 该主视图有几个子视图。

Messenger可以在主视图的视图模型与其子视图的视图模型之间发送消息。

可以使Messenger的范围受到限制,以便在打开两个主视图时与之交互只向该视图的子视图发送消息吗?

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

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

IMessenger接口的RegisterSend重载接受对象,以限制哪些注册者接收消息。 如果使用令牌发送消息,则唯一会看到该消息的对象是使用相同令牌为消息注册的对象。 在这里,“相同”表示对象相等,因此您可以将具有合理的相等语义且对您有意义的任何对象用于令牌,即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

对于您的情况,您将希望每个主视图模型都有自己的令牌,并将其令牌传递给子视图模型。

您始终可以在传递默认的IMessenger (具有静态 ,应用程序域范围)或创建Messenger的新实例之间进行选择:

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

当您不想控制Messenger的范围时,第一种方法很有用。 您可以将其视为中央枢纽。 “本地”信使非常适合在VM或某些容器内进行通信。

为什么这比拥有令牌更好? 当您拥有基于令牌的消息传递的高级应用程序时,您将在处理它们时遇到困难(选择正确的令牌)。 特别是在涉及依赖注入时。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM