5


4

階層データ構造でMVVMに編集を追加します

この質問は、https://stackoverflow.com/questions/3257673/c-mvvm-treeview-twoway-binding-of-hierarchical-data [this older]のフォローアップであり、オープンというよりも確認です質問。

私のViewModelインスタンスには、モデルのプライベートインスタンス `_modelInst`があります。 + ViewModelは、編集中にモデルのデータに排他的にアクセスできます(したがって、モデルはINotifyPropertyChangedを実装する必要はありません)。

ビューからモデルデータを編集する方法を思いついた3つの方法があります。

  1. モデルインスタンスで直接取得/設定
    e.g. for simple value fields + return _modelInst.fieldname; + _modelInst.fieldname = value; +これは簡単に実装できます…​

  2. * ViewModelインスタンスを作成し、親のデータを操作する 構造* +例 _構造体のような_より複雑なオブジェクトタイプの場合:

    • そのタイプの新しいViewModelを作成します。
      ViewModelは親とそのフィールド名を知っています。

    • ContentControl + DataTemplateに表示する

    • 取得/設定:+ パラメータとしてフィールド名を持つ親のメソッドを介して、+ 1つのフィールドのみが変更された場合でも元のオブジェクト全体を上書きする+これは、親によって実装された新しいインターフェイスを作成することを意味しますこれらの構造。

  3. 親の直接の知識なしでViewModelインスタンスを作成する データ構造 +例 親クラス内のクラス(のリスト)

    • クラスごとに新しいViewModelを作成する

    • 更新手順を親に送信する

  4. コマンド

  5. メッセージ

  6. リフレクション(親はどの子が関数を呼び出したかを知っている+ インスタンスを保存されているすべての子と比較します)+ *これらはすべて、実装可能な大きな混乱であり、編集可能なモデルのすべてのフィールドに関数を作成します。

(4.)リフレクションのみで動作する汎用ViewModelを作成できます。各サブオブジェクトは、その親とそのフィールド名(リストにある場合は+ index)を知っています。 +ルートのロジックのみがモデルに干渉します。 +しかし、このソリューションには、 `_modelInst`内のフィールドへのパスを保存する手段も必要です。

これを達成する他の(より単純な)方法はありますか? + MVVMの原則を誤解しましたか(もう一度)。 + MVVMは大規模な階層データ構造の操作に適していますか?

2 Answer


2


これらのリソースが役立つことを願っています。 MVVMと、ビューモデルを使用してオブジェクトグラフ/階層を表現する方法を学んだとき、それらは非常に役立ちました。

  1. http://www.paulstovell.com/editable-object-adapter [編集可能なオブジェクト アダプタ]

  2. http://www.paulstovell.com/editable-collection-adapter [編集可能 収集アダプター]

  3. MicroModels


0


これは素晴らしい質問であり、MVCパターンが付属している良い答えがあるとは思いません。

ViewModelsは、マップ先のモデルに子がない場合に最適に機能します。

しかし、次のようにモデルに子がある場合

顧客

        -->Order

        -->Country

(CountryはCustomerの子オブジェクトであると想像してください)デザインパターンの種類が壊れます。

私が見つけた最高のことは、継承を使用し、ビューモデルロジックが必要な子のみを選択的に公開することです。 それ以外の場合は、継承を介して取得されるビューのモデルのプロパティにアクセスします。

public class CustomerView:Customer // Customerから継承(モデル)\ {

public CustomerView(Customer customer)
{
      this.FirstName = customer.FirstName
      //etc..

      //Only if you need it, that is if you have some display-specific
      //logic relating to country for a given view, you create
      //a CountryView class that inherits from Country and gets populated
      //by an instance of it as well
      this.CountryView = new CountryView(customer.Country)
}

public CountryView CountryView {get;set;} //sadly you cannot override Country but you may be able to shadow it.

public string DisplayColor
{
    if(base.FirstName == "Joe")
    {
        return "red";
    }
    return "";
}

}

これは、孫を扱うときに面倒になります。 誰かがより良い解決策を持っているなら、私はそれを聞きたいです。

ありがとう