7

私はMVVM Lightを使用しており、パッケージ化されたメッセンジャーシステムを使用してビューモデル間の通信を行っていますが、ちょっとしたジレンマにぶつかりました! 基本的に、ユーザーが顧客レコードをクリックすると、対応するビューが開き、CustomerViewModelがインスタンス化されます。この時点で、CustomerViewModelは、以前のビュー モデル ( ViewAllCustomersViewModel ) から選択された顧客 ID を必要とするため、ビューがバインドする選択された顧客情報を取得できます (まだフォローしていますか?)。したがって、最初に考えたのは、 ViewAllCustomersViewModel (表示する顧客が選択されている場所) からCustomerViewModelへのメッセージでその ID を送信することでした...ただし、CustomerViewModelビューが読み込まれるまで (メッセージが既にブロードキャストされている時点で)、メッセージを受信できるようにインスタンス化されません!

では、この問題を解決する最善の方法は何でしょうか? これまでのところ、CustomerViewModelがインスタンス化された後にViewAllCustomersViewModelにリクエストを送信し(基本的には「メッセージを受信する準備ができています」と言っています)、次にViewAllCustomersViewModelが ID をCustomerViewModelに送り返すと考えてきましたが、これはこれを解決するために必要なアプローチは?私には少し醜いようです!

そうでなければ、私が抱えている問題を説明できるコミュニケーションの別の方法があると考えていましたか? しかし、これがメッセージング システムの要点ではないでしょうか...ビュー モデル間で通信できるようにするためでしょうか? または、起動時にビューモデルを強制的にインスタンス化できますか? もしそうなら、それはViewModelLocatorにどのように影響しますか?

問題の概要が明確に説明されていることを願っています。説明のために架空のビュー モデル名を使用しています。追加してほしい情報があれば、自由に編集または提案してください。

4

5 に答える 5

5

モデルを介して通信しようとしましたか? あなたのトピックを最後まで読むことができませんでしたが、これがViewModel間の通信方法です。どちらのビュー モデルにもセッションのインスタンスがあります。

public ViewModel1(ISession session)
        {
            _session = session;           
        }

public ViewModel2(ISession session)
        {
            _session = session;           
        }

このようにして、BDD (動作駆動型開発) でアプリケーションをテストするときに、ビューなしでアプリケーションをテストできます。のりがモデルです。

この図からわかるように、ビューなしでアプリケーションをテストできるはずです。 ここに画像の説明を入力

于 2013-09-26T14:30:27.633 に答える
4

2 つのビュー モデルが相互に通信している同じ状況に遭遇しました。Microsoft PRISM フレームワークを使用して発行および購読しました。

あなたの場合、CustomerViewModel は親ビューであり、ViewAllCustomersViewModel は子ビューです。

  1. プリズム フレームワーク "Microsoft.Practices.Prism.PubSubEvents.dll" をhttps://www.nuget.org/packages/Prism.PubSubEvents/からダウンロードします。

  2. プロジェクト「Microsoft.Practices.Prism.PubSubEvents.dll」にプリズム参照を追加します

  3. 通信モデムに使用されるカスタム クラスを作成します。

      class Notifications : PubSubEvent<string>
      {
    
      }
    
  4. IEventAggregator eventAggregatorプロジェクトのシングルトン インスタンスを作成 し、初期化します。

      public sealed class SessionInfo
      {
            public  IEventAggregator eventHanlder;
    
            private SessionInfo (){
    
            }
    
            private static SessionInfo _instance = null;
    
            public static SessionInfo Instance{
                    get{
                     lock (lockObj){
                      if (_instance == null) {
                        _instance = new SessionInfo ();
                        _instance.eventHanlder= new EventAggregator();
                       }
                   }
                      return _instance;
                   }
                 }
                }
    
  5. ポップオーバー モデル (ViewAllCustomersViwModel) ボタン イベントの処理とその中のコードの下に移動します。これで公開されました。

ViewAllCustomersViwModel.cs

      public void OnSelectedItem(Item item)
     {
            SessionInfo.Instance.eventHanlder.GetEvent<Notification>().Publish(item.id);

      }
  1. これらのイベント アグリゲーターは、必要な場所でサブスクライブする必要があります。したがって、親ビュー モデル (CustomerViewModel) に以下のコードを追加します。

CustomerViewModel.cs

       public class CustomerViewModel
      {
               public CustomerViewModel()
              {
                  SessionInfo.Instance.eventHanlder.GetEvent<Notifications>().Subscribe(OnReceivedNotification);

               }

        //Handling the notification 
    public void OnReceivedNotification(string itemId)
        {
            Debug.WriteLine("Item Id is :" + itemId);

        }


     }

詳細については:

https://sites.google.com/site/greateindiaclub/mobil-apps/windows8/communication betweenviewmodelsinwindows8mvvmpattern

于 2014-09-12T13:36:09.023 に答える
2

個人的には、MVVM-Light Messenger を使用していましたが、大量のメッセージが飛び交い、「魔法の」メッセンジャーを使用する感覚が好きではありませんでした。私がしたことは、次のリンクへの回答として概説されています

開始時に新しいViewModelにデータを渡す最良の方法

警告しますが、私は自分の質問に答えましたが、それが良いか悪いかは誰も確認していませんが、私の状況では機能し、MVVM-Light Messenger の必要性がなくなりました。私のプログラムは実装で複数のスレッドを使用するため、リポジトリ内のすべてのエントリを CurrentThread.ManagedThreadId をキーとしてディクショナリに変更しました。

于 2013-09-26T15:58:30.367 に答える