2012-11-12 58 views
3

我有一個奇怪的問題。Mvvm Light Messenger消息從未收到

我正在使用GalaSoft的MVVM Light框架,目前爲止一切正常。 我使用信使系統發送ViewModels之間的消息就好了,直到我試圖做到以下幾點:

我有一個單一類,GateKeeper,發送消息。

這個類不是一個ViewModel,因此不會從ViewModelBase繼承。

如果它發送消息,它不會被接收到任何地方。

我曾嘗試以下:

  1. ViewModeBaseGateKeeper繼承 - >沒有成功。
  2. 註冊GateKeeper接收消息,從而看看它是否會接收/接收實際發送的消息 - >沒有成功。
  3. 從辛格爾頓更改GateKeeper正常實例 - >沒有成功
  4. 創建未連接到一個視圖MVVM視圖模型,並讓它發送郵件,就像GateKeeper - >沒有成功

所有我的viewModel連接到一個視圖可以發送消息,他們將被接收。

它幾乎看起來像一個視圖模型必須「鏈接」到信使工作前的視圖,但伊莫。這是一個主要限制。

下面是當前非常簡化的設置。

在GateKeeper上調用ApplicationInitialize不會觸發在mainviewmodel上接收到的消息,也不會觸發GateKeeper類自身。

我希望有人對這個問題有建議。

謝謝..

示例設置: MainViewModel構造:

public MainViewModel() 
    { 
     Messenger.Default.Register<LoadViewMessage>(this, (message) => 
     { 
      if (message.Sender is GateKeeper) CurrentView = message.View; 
      else if (message.Sender is LoginViewModel) CurrentView = message.View; 
      else if (message.Sender is MenuItemBarViewModel) CurrentView = message.View; 
     }); 

網閘:

public class GateKeeper : IGateKeeper 
{ 
    private readonly IEmployeeService _employeeService; 

    #region Implementation of IGateKeeper 

    public void ApplicationInitialize() 
    { 
     Messenger.Default.Send<LoadViewMessage>(new LoadViewMessage(ObjectLocator.MainMapView), this); 
    } 

    public void LoginSucceeded(Employee employee) 
    { 
     //This is where we retrieve the available services for the current employee 
     //TODO: add methods for retrieving service info from backend 

     //Send a message that should make the mainview load the map into its currentview property 
     Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView), this); 
    } 

    #endregion 

    public GateKeeper(IEmployeeService employeeService) 
    { 
     _employeeService = employeeService; 

     //Test.. Is not triggered 
     //Just used for debugging, thus nothing happens inhere. 
     Messenger.Default.Register<LoadViewMessage>(this, (message) => 
     { 
      if (message.Sender is GateKeeper) ; 
      else if (message.Sender is LoginViewModel) ; 
      else if (message.Sender is MenuItemBarViewModel); 
     }); 
    } 

消息類別:LoadViewMessage

public class LoadViewMessage : MessageBase 
{ 
    public UserControl View { get; protected set; } 

    public LoadViewMessage(UserControl view, object sender): base(sender) 
    { 
     View = view; 
    } 

    public LoadViewMessage(UserControl view):this(view, null){} 
} 

PS:ObjectLocator是處理指出,問題在發送方法,謊稱對象的所有實例和它們的生命週期

@UPDATE LBugnion(MVVM光的生成器)一個NinJect類,其中i實際上是使用一個帶有令牌的Send的重載。

@this不會在我的情況下工作

Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView), this); 

@this會順利

Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView, this)); 

本來是要傳遞給loadViewMessage,而不是發送方法爲代幣

+0

我不知道爲什麼你的代碼不能正常工作,但我可以告訴你,它應該。消息傳遞系統與ViewModel/View關係無關。 – jv42

+0

您是否調試過(斷點)GateKeeper方法?例如,你正在使用一個非默認構造函數(帶參數),它是否被調用? – jv42

+0

Excatly。它應該可以工作,而且當我在視圖中使用的其他視圖模型中使用它時也可以。 我調試了所有的GateKeeper構造函數。我不知道爲什麼它不能在這裏工作。 – ThBlitz

回答

4

您的問題在發送方法上。您正在使用將令牌作爲第二個參數的方法的重載。你傳遞「this」作爲標記。這意味着你(可能是錯誤的)使用郵件的發件人作爲標記。

如果您使用令牌發送消息,則還需要使用相同的令牌註冊接收者(在這種情況下,與Send方法中使用的實例完全相同)。由於您沒有使用令牌註冊,因此Messenger不會發送此消息,這是一種優化機制。

我的猜測是你誤解了發送方法中令牌的用法。如果需要,令牌僅作爲構建「私人消息傳遞網絡」的一種方式,其中兩個對象可以使用相同的令牌來註冊/發送並建立專用通信。

在你的情況下,如果你想發送發送者與消息一起,你需要將發送者保存在消息本身中,這是MessageBase和派生類所做的。

希望這有助於

洛朗

+0

哦,不知道..我可以看到問題!參數「this」實際上應該是我的LoadViewMessage的一部分,但是由於錯誤,它成爲Send重載方法的一部分,因此變成了一個令牌。 非常感謝Laurent。 生病更新我的問題,以反映你的答案。問候 – ThBlitz