2012-11-12 57 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