2012-04-27 15 views
1

私はMVVMを使用していますが(まだまだ私は非常に新しくなっています)、少しパターンに苦しんでいます。私はネットワークとプラットフォームの2人の子供を持つミッションと呼ばれるオブジェクトを持っています。ミッションは、1対多のプラットフォームを持ち、1つまたは2つのネットワーク(常に存在するプライマリとオプションの代替)を持っています。 NetworkPlatformという名前のNetwork and Platformの子があり、それらの数はプラットフォームとネットワークの数に依存します.5台のプラットフォームがあり、代替ネットワークを定義していない場合は5台のNetworkPlatformがあります。プラットフォームが追加されました代替ネットワークが存在するかどうかによって、1つまたは2つのネットワークプラットフォームを追加する必要があります。同様に、以前に存在しなかった代替ネットワークを定義する場合、プラットフォームごとにネットワークプラットフォームを追加する必要があります。同上。MVVMのパターンと従属する子ども

私は、私はまだそれに対処する方法は非常にわからないので、私は別のものをコメントしました。この

public MissionFullDataViewModel(Mission mission):base(mission) 
{ 
MissionVM = new MissionViewModel(mission); 
PlatformsVM = new PlatformsViewModel(mission); 
PrimaryNetworkVM = new NetworkViewModel(mission, mission.PrimaryNetwork); 
//AlternateNetworkVM = new NetworkViewModel(mission, mission.AlternateNetwork); 
} 

のようないくつかの子のviewmodelsをインスタンス化するミッションのための傘のViewModelのようなものを持っています。ユーザーは、チェックボックスを使用して1つを選択するように指示しますが、アプリケーションは既存のデータを表示するために使用されるため、代替データが存在するかどうかを確認する必要があります。まだそれについてはあまり確かではありません。

私はNetworkViewModelでNetworkPlatformsを扱っています、彼らはこのようなのObservableCollectionです:

private ObservableCollection<NetworkPlatform> networkPlatforms; 
public ObservableCollection<NetworkPlatform> NetworkPlatforms 
{ 
get 
{ 
    if (networkPlatforms == null) 
    { 
      networkPlatforms = new ObservableCollection<NetworkPlatform>(Network.NetworkPlatforms); 
    } 
     return networkPlatforms; 
    } 
} 
} 

と私ははっきりとそのコレクションからNetworkPlatformを追加および削除するにはいくつかのメソッドを記述する必要があります。 私のプラットフォームは、PlatformsViewModelで観測可能なコレクションです。

private void ResyncPlatforms(int newValue) 
    { 
     int oldValue = this.Platforms.Count; 
     int diff = newValue - oldValue; 
     if (diff > 0) 
     { 
      for (var i = 0; i < diff; i++) 
      { 
       var newPlatform = new Platform(); 
       newPlatform.Mission = Mission; 
       this.Platforms.Add(newPlatform); 
       missionRepository.AddPlatformToMission(Mission, newPlatform);//TODO need to tell the Network VM to add a network platform 
      } 
     } 
     else 
     { 
      for (var i = 0; i > diff; i--) 
      { 
       var platToRemove = Platforms.Last(); 
       this.Platforms.Remove(platToRemove); 
       missionRepository.RemovePlatformFromMission(Mission, platToRemove);//TODO need to tell the Network VM to remove network platform 
      } 
     } 
    } 

リポジトリがLINQToSQLバックエンドへのCRUDオプションを持つラッパーです:私は、プラットフォームの数を指定するためのユーザのための数スピナーと新しいものを追加したり、このような最後のx個のものを削除する関数を持っています。 Add ...とRemove ...メソッドは、コミット時(ユーザーが保存するとき)に挿入/削除するようデータベースに指示します。

したがって、PlatformsVMがresyncメソッドでプラットフォームを追加/削除するときにNetworkPlatformを追加/削除するにはどうすればよいですか?

networkplatformsのコレクションを追加および削除するNetworkViewModelのメソッドにResync関数を呼び出すことができます。ユーザーが代替ネットワークをオンまたはオフに切り替えると、傘型ビューモデルで同様のことが起きる可能性があります。しかし、私のPlatforms VMはプライマリと代替ネットワーク(存在する場合)のNetworkviewModelsにアクセスする必要があるので、より良い方法が必要だと思うし、代替のときにそれを行う方法を実際に見ることはできませんネットワークがオンとオフに切り替わります。

私のnetworkviewmodelは、PlatformVMのPlatforms Observableコレクションの変更をリッスンする方が良いでしょうか?

私は何をすべきか明確ではなく、助けていただければ幸いです。ありがとう。

答えて

1

正しい、これは.NETでのイベントシステムでオブザーバーパターンで最適に処理されます。それは、物事を追加および削除されたときに、これだけのイベントをサブスクライブし、それに応じて反応して、CollectionChangedイベントを発行します。次のいずれかを実行できます

  • またはこれら2つのアプローチのObservableCollection

差があることが、二番目に、あなたのNetworkViewModel意志である上、既存のものを使用します(PlatformAdded & PlatformRemovedを考える)PlatformsViewModelに新しいイベントを追加より具体的にはPlatformsViewModelに結合してください。プラットフォームをどのように格納するのかを知る必要があり、このストレージは、処理する必要のあるイベントの観測可能な収集であることが必要です。

この通信の途中で集約ビューモデル(MissionFullDataViewModel)が人の一員として参加する場合、これは部分的に緩和される可能性があることに注意してください。 - PVM obserable collectionのイベントを購読し、NVMメソッドをこの。

いずれかの方法は、あなたが言う、これら2つのオブジェクトをバインドするために、あなたの集約ビューモデルを使用する必要があります。

public MissionFullDataViewModel(Mission mission):base(mission) 
{ 
    MissionVM = new MissionViewModel(mission); 
    PlatformsVM = new PlatformsViewModel(mission); 
    PrimaryNetworkVM = new NetworkViewModel(mission, mission.PrimaryNetwork); 

    // #1: direct binding -- tightly coupled 
    PlatformsVM.Platforms.CollectionChanged += NetworkVM.PlatformsChangedHandler; 
    // #2: direct binding -- less tightly coupled 
    PlatformsVM.PlatformAdded += NetworkVM.PlatformsChangedHandler; 
    PlatformsVM.PlatformRemoved += NetworkVM.PlatformsChangedHandler; 
    // #3: indirect binding -- less tightly coupled 
    PlatformsVM.Platforms.CollectionChanged += this.HandlePlatformsChange; 
    // #4: indirect binding -- loosely coupled 
    PlatformsVM.PlatformAdded += this.HandlePlaftormsChange; 
    PlatformsVM.PlatformRemoved += this.HandlePlatformsChange; 
} 

HandlePlatformsChange

Mediatorパターンユーティリティの一種として機能します。最後に NetworkVMで適切なメソッドを呼び出す前に、 PlatformsVMイベントからのデータを準備する可能性があります。

最後のシナリオでは、誰も何も知らない - タスクを実行するために必要なデータ。そして、これは私が示唆しているアプローチです。プラットフォームとネットワークはあまり知り合う必要はなく、結合論理は、これらの2つの方法についてどちらかを知っているエンティティによって実行されます(MissionFullDataViewModel)。

+0

#3と#4では何でしょうか.HandlePlatformsChange do - NetworkVMのハンドラを呼び出すだけですか?申し訳ありませんがイベントになると私は少しダンスですが、私はそれらをあまり使用していない。 – Nix

+0

ええ、たぶんあなたのケースでは、NetworkVMの 'update'関数を呼び出すメソッドにすぎないでしょう。 :) –

+0

@Nix:ほとんどの単純なケースでは、NetworkVMハンドラを呼び出すだけです(入力に合わせてデータを修正することも可能です)。より高度なケースでは、あらゆる種類の検証、準備、何もできません(「NetworkVM」はハンドラを公開する必要さえないかもしれません)。 –

1

申し訳ありませんが、私は本当にあなたが望むものに正確に従うことができません。もう少し簡潔にする方法はありますか?

私のnetworkviewmodelが への変更PlatformVMのプラットフォーム監視可能なコレクションをリッスンし、どのようにあれば持っている方が良いでしょうか?

ここで私は答えることができます。ObservableCollectionは、よく観察できます。

private void SubscribeToPlatformChanges() 
{ 
    ((INotifyCollectionChanged)_PlatformVM.Platforms).CollectionChanged += (s, e) => 
    { 
     switch (e.Action) 
     { 
      case NotifyCollectionChangedAction.Add: //platforms were added - use e.NewItems 
      case NotifyCollectionChangedAction.Add: //platforms were removed - use e.OldItems 
      case NotifyCollectionChangedAction.Reset: //all platforms were removed 
     } 
    } 
}