Messenger 前回までで、足し算プログラムの基本的な部分はできました。 ですが、例えば計算が終わったあと、ダイアログを表示する場合はどうでしょうか。 今ViewModelからViewへの通知はBindingのINotifyPropertyChangedしか方法がありません。 INotifyPropertyChangedではViewでダイアログを表示することは出来ないので別の方法が必要になります。 それがMessengerです。 Messengerは、ViewModelやModelからViewに通知したいときに一意の文字列とパラメータを渡してViewに通知を行うことができます。 計算終了をMessengerで通知する 通知を行うMessengerはMessenger.Defaultで取得することができます。 今回はMainViewModel.csのCalcCommandで計算が終わったとに、Messengerで通知を送ってみましょう。

Sendメソッドは送りたいメッセージのパラメータ、送りたいメッセージの一意の名前を引数としています。 ではMainPage.xaml.csのコンストラクタ内にMessengerのメッセージを受信する処理を書きましょう

Calcボタンをクリックすると計算結果がダイアログで表示されれば完成です。

Command MVVMにおいて、Viewで受け付けるユーザーからの入力(Buttonを押すなど)はCommandとしてViewModelで処理を行います。 CommandはICommandインターフェースを実装したクラスが必要となります。 MVVMLightToolkitではRelayCommandというクラスがあるのでこれをつかって、Commandを実装してきます。 Commadを実装するところは、ViewModelになります。 MainViewModel.csのメンバとして、RelayCommand型のCalcCommandを追加します。

続いて、CalcCommandを初期化するために、コンストラクタで CalcCommandをnewします。そのとき、コンストラクタ引数としてActionをいれます。 そうすることで、そのCommandを実行した時、Action内が呼び出されます。 つまり、ViewからCommandが送られたら、Command内のActionを実行し、Action内部でModelを使って計算を行います。

MainViewModel.csの全体はこのようになります。

ViewからCommandを呼び出す では、ViewからCommandを呼び出してみましょう。 今回はButtonが押されたときにCommandを実行できればよいので、 ButtonのCommandプロパティにCalcCommandをBindingします。 ButtonはClickイベントに反応してCommandプロパティにバインドされているCommandを実行しますが、もし他のイベントなどに反応させたかったらビヘイビアを使います。

これでCommandは実装できました。 実行して、Calcボタンを押すと2つの値が足されていたら成功です。

Binding 前回、ViewとModelとViewModelのファイルの疎結合を行いました。 続いて足し算に用いるデータである1つめの値、2つめの値、1と2を足した結果の3つのint型のデータをBindingでViewと疎結合を行います。 Bindingについて知らない人はWindowsストアアプリプログラミングTipsのBindingの章を見てください。 まず、データBindingを行うには、Bindingしたいコントロール(3つのTextBox)のDataContextプロパティにBindingしたいデータ(Value1,Value2,Resut)を入れる必要があります。 今回の場合、TextBoxのDataContextは親コントロールであるPageクラスのDataContextと同じものになるので PageクラスのDataContextにMainViewModelを入れます。 MainPage.xamlのPageタグに名前空間を追加して、

DataContextプロパティにMainViewModelを入れます。

次に3つのTextBoxにBindingの構文を書きます。 今回DataContextはMainViewModelなのでBindingのPathはSumModel.Value1となります。

ModeはTextBoxの入力もModelに反映したいのでTwoWayとなります。 ViewModelから変更通知を送る 続いて、ViewModelやModelからViewに変更通知を送るためにINotifyPropertyChangedインターフェースを実装して変更通知をViewに送信します。 MVVMLightToolkitの場合、ViewModelBaseがINotifyPropertyChangedを実装していて、 「RaisePropertyChanged」メソッドを実行するだけで変更通知を送ることができます。 フィールドの値が書き換えられた時に通知を行うので プロパテイのセッターにRaisePropertyChangedを書きます。 MainViewModel.csのSumModelのところをこのようにします。 RaisePropertyChangedメソッドの引数にはプロパティ名をstring型でいれます。

Modelから変更通知を送る ModelもRaisePropertyChangedメソッドによって変更通知を行います。 RaisePropertyChangedはObservableObjectクラスのメソッドなので継承しているので使うことができます。

これでModelからの変更通知を送ることができました。 ModelであるSumクラスはこのようになります。 今回は、値の確認のためにコンストラクタでValue1とValue2に適当な値を入れます。

ViewとModelの値の同期がとれていれば成功です。

Viewを作る 今回は単純な足し算をするプログラムをMVVMで作ります。 まず、ViewにあたるXAMLを作ります。 今回のViewは最初に作成されたMainPage.xamlを使います。 MainPage.xamlをこのようなページにしましょう。 1つめのたす値であるTextBoxと2つめのたす値であるTextBox、更に足した結果を表示するTextBox、 計算開始するButtonが設置されていれば大丈夫です。 XAMLはこのようにしました。

Modelを作る 次に計算に用いる値と、計算する処理を保持するModelクラスを作ります。 今回の場合、Modelにあたるのは「足し算」という概念なのでSumクラスを作ります。 SumクラスはObservableObjectを継承します。 ObservableObjectはMVVMLightToolkitのクラスです。

続いて、Sumクラス内にフィールドを作ります。 足し算Modelは、フィールドとして ・1つめのたす値(int型) ・2つめのたす値(int型) ・足した結果の値(int型) の3つのフィールドを所持する必要があります。 (なぜなら値が2つとその結果1つがないと足し算ができないから) MVVMを実現するにあたって、後々のことを考えて、フィールドをプロパティでカプセル化する構造にする必要があります。

次に足し算を行うメソッドをつくります。 これは簡単で、自身のフィールドであるValue1とValue2を足した結果をResultにいれるだけです。

Sumクラス全体はこのようになります。

ViewModelを作る 最後にViewとModelとの橋渡しを行うViewModelを作成します。 MVVMLightToolkitを入れると、すでにViewModelフォルダにMainViewModelが入ってるのでこれをそのまま利用します。 ViewModekはModelを所持するので、今回のModelであるSumクラスをフィールドとして所持し、プロパティでカプセル化します。

自分でViewModelを作る場合は、MVVMLightToolkitのViewModelBaseクラスを継承する必要があります。 これでMVVMに必要な基本的なファイル構造は完成しました。 もちろん、別のページ(View)にも適用させたかったらViewが複数必要ですし、引き算も実行させたかったら引き算のモデルクラスを作る必要があります。 ただし、MVVMを実現するにあたって、最低View、Model、ViewModelの3つが必要となります。 基本的なファイル構造は完成しましたがこのままではプログラムは足し算をしてくれません。 次回以降で徐々にViewとModelとViewModelをつなげていきます。

MVVMLightToolkit MVVMを実現するには、ICommandインターフェースを実装したオリジナルのCommandクラスや、INotifyPropertyChanagedインターフェースを実装したりなど、 そこで、すでにいろいろな機能が実装されているMVVMLightToolkitを導入します。 その他のライブラリとしては、Livetなどが有名です。 MVVMLightToolkitはNugetからインストールできます。 参照設定を右クリック→[Nugetパッケージの管理]を押します。 検索ボックスに「mvvmlight」と入力し、検索してMVVMLightToolkitをインストールします。 これでプロジェクトにMVVMLightToolkitをインストールすることができました。