奇妙な問題があります。
GalaSoft の MVVM Light フレームワークを使用していますが、これまでのところすべて正常に動作しています。次のことを試みるまで、メッセンジャーシステムを使用してViewModel間でメッセージを送信しています。
GateKeeper
メッセージを送信するシングルトン クラス があります。
このクラスは ViewModel ではないため、 から継承されませんViewModelBase
。
メッセージを送信しても、どこにも受信されません。
私は次のことを試しました:
- から
GateKeeper
継承さViewModeBase
せます->成功しません。 - メッセージを受信するように登録
GateKeeper
して、実際にそれ自体から送信されたメッセージをキャッチ/受信するかどうかを確認します->成功しません。 GateKeeper
シングルトンから通常のインスタンス化への変更-> 成功なしGateKeeper
ビューに接続されていない MVVM ViewModel を作成し、 -> no Success のようにメッセージを送信できるようにする
ビューに接続されているすべてのビューモデルはメッセージを送信でき、受信されます。
メッセンジャーが機能する前に、ビューモデルをビューに「リンク」する必要があるように思えますが、imo. それは大きな制限です。
以下は、現在の非常に単純化されたセットアップです。
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 は、オブジェクトのすべてのインスタンス化とそのライフサイクルを処理する NinJect クラスです。
@UPDATE LBugnion (MVVM Light の作成者) は、トークンを取る Send のオーバーロードを実際に使用していた send メソッドに問題があることを指摘しました。
@これは私の状況では機能しません
Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView), this);
@これはうまくいく
Messenger.Default.Send(new LoadViewMessage(ObjectLocator.MainMapView, this));
これは、トークンとして Send メソッドではなく、 loadViewMessageに渡されるはずでした。