2015-07-20 25 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)實現。 –

相關問題