for WPF developers
ここでは、MVVM パターンの要となるデータバインディング機能を実現するための INotifyPropertyChanged インターフェースについて紹介します。 MVVM パターンでは、アプリケーション内部構造を下図のように Model、View、ViewModel の 3 つに大別します。 このとき、View と ViewModel でデータを連携する手段としてデータバインディング機能を用います。
MVVM パターンでは、View は ViewModel が公開しているプロパティを参照してそのデータをユーザに見せます。 このとき、ViewModel のプロパティの値が変更したかどうかを知るために用いるのが INotifyPropertyChanged インターフェースです。 逆に View 上でその値が変更されたかどうかを ViewModel が知る必要がありますが、 これは WPF の仕組み上既に備わっている機能で、開発者が明示的に何かをする必要はありません。
INotifyPropertyChanged インターフェースのメンバは次のひとつだけです。 コメントにもあるように、INotifyPropertyChanged インターフェースを備えたクラスは、 プロパティ値が変更されたときに PropertyChanged イベントを発生させなければいけません。
それでは、ここで簡単な View をひとつ作成し、 INotifyPropertyChanged インターフェースを備えた ViewModel とデータバインドする例を作成しましょう。 WPF アプリケーション開発のためのプロジェクトはこちらで紹介している方法で作成したプロジェクトを使用します。
まず MainView.xaml を Code 2 のように編集します。 縦にコントロールを並べる StackPanel コントロールの中に、TextBox コントロール、TextBlock コントロール、Button コントロールを ひとつずつ配置しただけのシンプルな画面です。 これをコンパイルすると Fig.2 のような画面が表示されます。
データバインディング機能を使うために、ViewModel 側に INotifyPropertyChanged インターフェースを実装したプロパティを定義します。 YKToolkit.Controls.dll を利用することで INotifyPropertyChanged インターフェースが既に実装されたクラスを扱うことができますが、 ここでは敢えて INotifyPropertyChanged インターフェースを自前で実装して、その内部構造を知ってもらおうと思います。
INotifyPropertyChanged インターフェースを MainViewModel に実装すると次のようなコードになります。
INotifyPropertyChanged インターフェースの目的は、View 側に ViewModel のプロパティが変更されたことを通知することです。 したがって、ViewModel 側で公開しているプロパティに変更があったときに、RaisePropertyChanged() メソッドをコールする必要があります。
具体例として、Text プロパティおよび Result プロパティを次のように定義します。 それぞれの get アクセサでは、private フィールドの内容をそのまま返しています。set アクセサでは、private フィールドで保持している値と異なる値がセットされようとしたとき、private フィールドの内容を更新するとともに RaisePropertyChanged() メソッドをコールすることで、対応するプロパティが変更されたことを View 側に通知しています。
ここでは Text プロパティが変更されたとき、すべて大文字にした文字列を Result プロパティに設定するようにしています。
次に、これらのプロパティを参照するように、MainView を次のように変更します。
コンパイル、実行すると、
Buton コントロールおよび TextBox コントロールの中身が MainViewModel で定義した Text プロパティの内容と一致するようになるため、起動直後は空白となります。
TextBox コントロール内のテキストを変更した後、TextBox コントロールのキーボードフォーカスを外す(Tab キーを押す)と、TextBlock コントロールのテキストが変化します。
これは、Text プロパティの変更によって Result プロパティが変更され、その変更が TextBlock コントロールの Text プロパティに伝わっているからです。
(a) 起動直後 (b) テキスト変更後
View 側からのプロパティ変更通知のタイミングは設定によって変更できます。 デフォルト値は LostFocus といって、フォーカスを失ったときに通知されるようになっています。 テキスト内容を変更した時点で MainViewModel にその変更が通知されるようにする場合は、PropertyChanged という設定値にする必要があります。 具体的なコードは次のようになります。
Designed by CSS.Design Sample