WPF_MVVM構造について
WPFにおけるMVVM
MVVMとは、プログラムを Model View ViewModel の3要素に分割して設計するデザインパターンです。
ViewModel は Model に依存し、View はViewModelに依存するという構造となります。
View
ViewはUIに関連する部分であり、ユーザーに操作されたり、データを表示してユーザに伝えたりします。
WPFでは「.xaml」と「.xaml.cs」が相当します。
ViewModelが保持するデータを利用してUIを描画し、UIへの操作をViewModelに通知(アクションを送信)します。
ViewModel
ViewModelはModelとViewModelの仲介を担当します。
ModelのデータをView(UIの描画)に必要な情報に変換したり、Viewから送信されたアクションをModelに通知します。
Viewを意識した実装(Viewが必要とするデータやコマンド)が必要ですが、Viewに依存しないように実装する必要があります。
Model
Modelはデータ構造とロジック(データの取得や加工)を担当します。
より簡単にいえば、View と ViewModelが請け負わない部分を請け負います。
MVVM構成
依存関係
MVVMの各要素は Model ← ViewModel ← View の単一方向に依存しています。
ViewとModelは疎通せず、お互いの存在を知らない構成となります。
public class Model { }
public class ViewModel
{
private Model _model;
public ViewModel(Model model)
{
_model = model;
}
}
public class View
{
private ViewModel _vm;
public View(ViewModel vm)
{
_vm = vm;
}
}
...
Model model = new Model();
ViewModel vm = new ViewModel(model);
View view = new View(vm);
MVVMの禁止事項
MVVMの各要素は Model ← ViewModel ← View の単一方向に依存しています。
少なくともModel と View が依存する構造にしてはいけない関係となります。
View
ViewがModelの存在を知っている構造は禁止事項です。ViewとModelは疎通しません。
ViewがViewModelのプロパティを直接操作することは禁止事項です。
View内でViewModelを差し替えることは禁止事項です。
ViewModel
Viewの存在を知っている構造は禁止事項です。
ただし、Viewが必要とするデータやコマンドを用意する必要があるので、依存しない範囲で知っていることは許容されます。
ViewModelがModelのプロパティを直接操作することは禁止事項です。
ViewModel内でModelを差し替えることは禁止事項です。
Model
ViewやModelを知っている構造は禁止事項です。
Modelは独立した構成となる必要があります。
MVVMの思想について
MVVMはViewのデザインパターンである。
MVVMはアプリケーションのアーキテクチャではなく、Viewのデザインパターンです。
MVVMでは、Viewの関心事はView層とViewModel層に、それ以外はModel層に配置します。
コードビハインド(Code Behind)とは
ユーザーインターフェース(画面表示)とプログラム(ロジック)を別のファイルに分けることをコードビハインドといいます。
デザイナとプログラマが分業できるようにするための仕組みです。
C#では「コードビハインドに記述しない」といった説明がされますが、ここでのコードビハインドとは「.xaml」ファイルに付随する「.xaml.cs」ファイルを指しているケースが多いです。MSがこのファイルを「the code-behind of a view」と説明したため、あいまいな意味で広まってしまったようです。
DataContextは単純にするべき。
ViewModelをViewのDataContextとしますが、DataContextにはViewからのBindingに関連しない機能を持たせてはいけません。
DataContextは薄く、単純にするべきです。
関連ページ
- WPF_ViewModelデータバインディング
- WPF_MVVM構造について
- WPF_INotifyPropertyChangedインターフェース
- WPF_ICommandインターフェース
- WPF_IDataErrorInfoインターフェース
- C#