I have a strange problem.
I'm using the MVVM Light framework from GalaSoft and everything so far works fine. I'm using the messenger system to send messages between ViewModels just fine, until I tried to do the following:
I have a singleton class, GateKeeper
, that sends messages.
This class is NOT a ViewModel and thus does not inherit from ViewModelBase
.
If it sends a message it is not received anywhere.
I have tried the following:
- Letting
GateKeeper
inherit fromViewModeBase
-> No success. - Registering
GateKeeper
to receive messages, thus seeing if it would catch/receive the message that was actually sent from itself -> No Success. - Changing
GateKeeper
from Singleton to normal instantiation -> no Success - Creating a MVVM ViewModel that is not connected to a view, and letting it send messages, just like the
GateKeeper
-> no Success
All my viewModels that are connected to a view can send messages and they will be received.
It almost seems like a viewmodel must be "linked" to a view before the messenger works,but imo. that is a major limitation.
Below is the current, very simplified setup.
Calling ApplicationInitialize on GateKeeper does not trigger a message received on the mainviewmodel nor the GateKeeper class itselves.
I hope that someone has suggestions to this problem.
Thanks..
Example setup: MainViewModel constructor:
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;
});
GateKeeper:
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);
});
}
Message class: 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 is a NinJect class that handles all instantiation of objects and their lifecycle
@UPDATE LBugnion (Creator of MVVM Light) pointed out that the problem lied in the send method, where i was actually using a overload of Send that takes a token.
@This will not work in my situation
Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView), this);
@This WILL work
Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView, this));
this was supposed to be passed to the loadViewMessage and NOT the Send method as a token
GateKeeper
methods? For instance, you're using a non-default constructor (with parameter), is it called? – jv42