1

私はMVVMを使用していますが(まだ-私はそれに非常に慣れていません)、パターンに少し苦労しています。Network と Platform の 2 つの子を持つ Mission というオブジェクトがあります。ミッションには 1 つから多くのプラットフォームがあり、1 つまたは 2 つのネットワーク (常に存在するプライマリとオプションの代替) があります。NetworkPlatform と呼ばれる Network と Platform の子があり、それらの数はプラットフォームとネットワークの数によって異なります - 5 つのプラットフォームがあり、それらが代替ネットワークを定義していない場合、5 つの NetworkPlatforms が存在し、それ以外の場合は 10 になります。プラットフォームが追加されました 代替ネットワークが存在するかどうかに応じて、1 つまたは 2 つのネットワーク プラットフォームを追加する必要があります。同様に、以前は存在しなかった代替ネットワークを定義することを選択した場合、プラットフォームごとにネットワーク プラットフォームを追加する必要があります。同上除去。

このようないくつかの子ViewModelをインスタンス化するMission用の一種の傘ViewModelがあります

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);
}

まだ対処方法がよくわからないため、代替のものにコメントしました。ユーザーはおそらくチェックボックスを使用して必要なことを示すでしょうが、アプリケーションは既存のデータを表示するためにも使用されるため、別のデータが存在するかどうかを判断する必要があります。それについてはまだよくわかりません。

私は NetworkViewModel で NetworkPlatforms を扱っています。これらは次のような観察可能なコレクションです。

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

そのコレクションに NetworkPlatform を追加および削除するためのメソッドをいくつか記述する必要があることは明らかです。私のプラットフォームは、PlatformsViewModel の観察可能なコレクションです。ユーザーがプラットフォームの数を指定するための数値スピナーと、次のように新しいものを追加したり、最後のxのものを削除したりする関数があります。

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 オプションを備えたラッパーです。Add... および Remove... メソッドは、コミット時に (ユーザーが保存したときに) 挿入/削除するようにデータベースに指示します。

では、PlatformsVM が再同期メソッドでプラットフォームを追加/削除するときに、NetworkVM に NetworkPlatforms を追加/削除するにはどうすればよいですか?

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

私の networkviewmodel が PlatformVM の Platforms オブザーバブル コレクションへの変更をリッスンするようにしたほうがよいでしょうか。

私は何をすべきか本当に明確ではありません。助けていただければ幸いです。ありがとう。

4

2 に答える 2

1

正解です。これは、.NETではイベントシステムであるオブザーバーパターンで処理するのが最適です。次のいずれかを実行できます。

  • PlatformsViewModel(think PlatformAddedPlatformRemoved)に新しいイベントを追加します
  • または既存のものを使用するObservableCollection

これらの2つのアプローチの違いは、2番目のアプローチでは、NetworkViewModelより多くの結合が得られることPlatformsViewModelです。プラットフォームをどのように格納するか、およびこのストレージがどのイベントを処理する必要があるかを監視可能なコレクションであるかどうかを知る必要があります。

集約ビューモデル(MissionFullDataViewModel)がこの通信の途中で一種の人間として参加する場合、これは部分的に軽減される可能性があることに注意してください。これは、PVMの監視可能なコレクションのイベントをサブスクライブし、これに対する応答として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一種のメディエーターパターンユーティリティとして機能します。PlatformsVMで適切なメソッドを最終的に呼び出す前に、イベントからのデータを準備する場合がありNetworkVMます。

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

于 2012-04-27T13:03:27.727 に答える
1

申し訳ありませんが、ご希望に沿うことができません。もう少し簡潔にする方法はありますか?

Networkviewmodel が PlatformVM の Platforms オブザーバブル コレクションへの変更をリッスンするようにしたほうがよいでしょうか?

これで私は答えることができます。ObservableCollection は、まあ、観察可能です。物事が追加および削除されると CollectionChanged イベントを発行するため、イベントをサブスクライブしてそれに応じて反応するだけです。

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
        }
    }
}
于 2012-04-27T12:53:38.177 に答える