MVVM:VM オブジェクトは M オブジェクトを直接公開する必要がありますか、それとも M のゲッターに委任するゲッターを通じてのみ公開する必要がありますか?
-
12-09-2019 - |
質問
説明する最良の方法は、次の例を使用することです。
これがモデルです
public class Person
{
public int age;
public string name;
}
これはビューモデルです
public class PersonVM
{
}
私の質問は次のとおりです。
vm はユーザーをデータ テンプレートに公開するべきでしょうか、それともモデル プロパティを独自のプロパティでカプセル化すべきでしょうか?
解決
ビューモデルは、独自のプロパティを宣言し、ビューからモデルの詳細を非表示にします。これはあなたの最も柔軟性を提供し、モデルクラスに漏れるビューモデルタイプの問題を保つことができます。通常、ビューモデルクラスは、委任によってモデルをカプセル化します。たとえば、
class PersonModel {
public string Name { get; set; }
}
class PersonViewModel {
private PersonModel Person { get; set;}
public string Name { get { return this.Person.Name; } }
public bool IsSelected { get; set; } // example of state exposed by view model
public PersonViewModel(PersonModel person) {
this.Person = person;
}
}
注意:モデルは、それを消費しているビューモデルについて何も知らないはず、とビューモデルがそれを消費しているビューについては何も知りません。ビューは、背景に潜むモデルについて何も知らないはずです。したがって、ビューモデルのプロパティの背後にあるモデルをカプセル化します。
他のヒント
その質問に関しては一般的な合意はありません。たとえば、これは Ward Bell によって策定された MVVM に関する未解決の質問の 1 つでした。 ここ:
VMは、Vに包装されていないMオブジェクト(例えば、生の従業員)を提供することを許可されていますか?または、M-Objectのプロパティ(プロパティを持つことさえ許可されている場合でも!)をVMラッパーの表面からのみ露出する必要がありますか?
VM でモデルを直接公開しないことの主な利点は次のとおりです。
これを「強力なコンバータ」として使用し、ビューに便利な方法でモデル値をフォーマットすることができます。
ユーザーインターフェイスに関連する他の機能を注入できます。 データ検証メッセージ, 元に戻すやり直し,..
短所は次のとおりです。
ビューモデル内のすべてのモデル プロパティを公開するには、多くのコードを複製する必要があります。
ビュー コントロールを viewmodels プロパティにバインドすると、viewmodel から propertyChanged イベントが送信されます。しかし、ビューモデル セッターとは異なる他のソースからモデル プロパティが変更された場合はどうなるのでしょうか?次に、ビューモデルに通知する必要があるため、2 つの OnPropertyChanged (モデル内に 1 つ、ビューモデル内に 1 つ) で終了します。かなり複雑です!
したがって、私にとっての正しい答えは次のとおりです。それはあなたの要件によって異なります。
これに対する興味深いソリューションは、MSDNのボリューム25にロバート・マッカーターによって提案された。
http://msdn.microsoft.com/en-us/magazine/ ff798279.aspxする
彼は、モデルのすべてのプロパティをプロキシ回避しながら、モデルの上に層を提供するために、動的なビューモデルを使用します。
あなたの問題空間は、(ダイナミクスは、パフォーマンスヒットを被る行う)高いパフォーマンスを必要としない場合は、、これは優れたソリューションです。ビューは、モデルについて何を知っている必要はありませんが、ビューモデルが提供されているプロキシのプロパティを持っていない「であると。」いつでもプロパティが表示またはモデルを変更することなく、モデルのプロパティをラップするビューモデルに追加することができます。詳細は、記事を読んでます。
すべてのモデルのためのViewModelを持つことは、それよりも悪いかもしれません。あなたがモデルの階層構造、あるいは簡単なコレクションを持っている場合は? その場合、あなたはすべてのモデルを反復処理ごとのモデルViewModelにインスタンスを構築し、また通知変更イベントや他のイベントを登録する必要があります。 IMHO、これは完全に非常識な、と無理があります。 DaniCEが言ったように、あなたは多くのコードと大きな頭痛の種になってしまいます。