残念ながら、あなたはいくつかのことを混同しました。MVVMの基本は
- モデル - アプリケーションが処理しているデータが含まれています。できるだけシンプルに保つ必要があります。
- ViewModel - アプリケーションの状態を反映し、ビジネス ロジックを含みます。ビジネス層です。
- View - ViewModel を解釈して、ビジネス レイヤーとその状態を視覚的に表現します。
この 3 つの部分を使用すると、関心の分離と分離されたアーキテクチャを提供するのは非常に簡単です。もっと読みたい場合は、ここをクリックしてください。
質問に戻る:
その特定のケースでは、Group と Contact と呼ばれる 2 つのモデル (データ クラス) があります。グループには連絡先のリストが含まれています。どちらも INotifyPropertyChanged インターフェイスを実装しています。
それは少し奇妙です。INotifyPropertyChanged
通常、 VM はビューからの値の変更を処理する必要があるため、モデル クラスに実装する必要はありません。
しかし、そのメカニズムをモデル層にも持つことは想像に難くありません。ただし、このレイヤーの変更を追跡したくないため、VMが処理する必要があるため、必要ありません。
[...] xaml にバインドされている ViewModel に上記のようなプロパティを 1 つ持つか、モデルごとに ViewModel を作成します (GroupViewModel や ContactViewModel など) [...]
はい、これは通常のアプローチです。ビューレイヤーに渡す必要があるモデルクラスごとに、ViewModel
.
[...] リストを持つ ObservableCollections の代わりに。
それは間違いなくいいえです。 を使用するList<T>
と、ビューはコレクションへの変更 (追加、削除) を認識しません。
最善の方法は何ですか(設計上)?モデルまたはビューモデルを xaml にバインドする必要がありますか?
MVVMに固執するだけです。ビューは VM を認識していますが、VM はビューを認識していません。さらに、VM はモデルを認識していますが、モデルはそれを認識していません。つまり、常に VM をビューにバインドする必要があります。
編集
以下は完全に合法です。
public class Address : ViewModelBase // implements INotifiedPropertyChanged a.s.o.
{
public string Street { /* you know what comes here */ }
public string ZipCode { /* ... */ }
public string City { /* ... */ }
/* more properties */
}
public class Person : ViewModelBase
{
public string Name { /* ... */ }
public Address Address { /* ... */ }
}