【WPF】MVVMでの実装の仕方[実例付き]

記事内に広告を含みます

MVVMについて

MVVMは、ソフトウェアの構造を階層的に整理したデザインパターンの名称です。

中でも、主にクライアントサイドのGUI(グラフィカルユーザーインターフェース)を持つアプリケーション開発で使用されることが多いように思います。

MVVMにおける階層は『Model』、『View』、『ViewModel』の3つに分けられ、ユーザーがアプリケーションに対して行った操作はViewで受けることになるのですが、この操作はCommandとして実行され、イベントとしてModelまで伝えられます。

そして、Modelで処理が完了すると、処理結果がViewまで伝えられ画面上に表示されます。

例えば、電卓アプリであれば「計算結果表示」というCommandが実行されたときに、Viewからイベントが伝わっていってModelのCalc()メソッドが呼び出され、計算が完了すると結果をViewまで伝えて表示するイメージです。

MVVMで開発したアプリケーションの処理フローのイメージ

MVVMで開発するメリット

MVVMパターンでのアプリケーション開発には、以下のようなメリットがあります。

  • ビューとビジネスロジックを明確に分けることができる
  • 階層毎に責務が明確に分かれているため、画面の仕様変更はビューだけで完結できる(ビジネスロジックは変更不要)
  • UI設計とビジネスロジック設計のそれぞれを並列に開発することができる

階層ごとの役割

View

ビューに関するコードを配置する階層です。

ここに書くコードはGUIのレイアウトに関するものだけです。
つまり、『ユーザーにどう見せるか』に関するコードだけを書くことになります。

ViewModel

ViewとModelの間に位置し、両者のデータおよびイベントの中継役となる階層です。

View→Modelに対しては、操作に応じてModelのデータを更新したり、メソッドを呼び出します。
一方、Model→Viewに対しては、Modelでの演算結果やデータをViewで表示できる形式に加工します。

Model

データベースへのアクセスや、様々な演算処理を行うビジネスロジック階層です。

『〇〇されたら××する』という演算機能は、この階層に集約します。

階層間のやりとり

階層を分けたからといってすべてがうまくいくわけではありません。

階層間の繋がりが“密”(密結合)になっていては、階層ごとに分けた意味が半減してしまいますので、なるべく階層間の結合は疎結合にする必要あります

MVVMでは階層間のやりとりを以下のように行うことを心がけます。

  • ViewとViewModel間のデータの伝達はDataBindingを用いて行う
  • ViewからViewModelへの操作の伝達はCommandsで行う
  • ViewModelからModelへのイベント通知は引数なしのメソッド呼び出しのみ行う
  • ModelからViewModelへのデータの変更通知はPropertyChanged イベントで行う
金欠ぱとろん
金欠ぱとろん

ViewModel~Model間の接続の仕方について解説しているサイトは少なく感じます。

もう少し読み進めて是非自分のものにしてください。

MVVMでの実装例

実装例を以下に示します。

なお、この実装例は「prism」というMVVMフレームワークの利用を前提にしていますので、prismについて詳しく知りたい方は以下記事をご参照ください。

ユーザが操作を開始してから表示が変化するまでの処理の流れを以下で解説します。

WPFによるMVVMの実装イメージ
ユーザーの操作

ユーザーがボタンを押す。

操作のCommand発行

ViewModelのXXX_Clickedコマンドが発行されてXXX_Clicked()に処理が移る。

引数なしメソッドの呼び出し

ViewModelからModelのMethod()が呼び出される。

金欠ぱとろん
金欠ぱとろん

このとき、ViewModelからは引数なしのメソッドだけを呼ぶようにModel側を設計します。

メソッドの処理実行

ModelのMethod()内の処理を実行し、プロパティ値を更新する。

プロパティ変更通知イベントを発行

Modelのプロパティ値の変更通知(PropertyChanged)イベントを発行する。

プロパティ変更通知イベントを伝播

ModelのPropertyChangedイベントを受けて、ViewModelのPropertyChangedイベントを発行する。

データバインディングで画面に表示

PropertyChangedイベントによって、ViewModelのプロパティ値がViewのTextBoxに反映される。

階層間での処理の伝播がどう行われるのかが理解できたかと思います。

その他にもDIコンテナを利用して、より疎結合な構成になるような工夫も可能です。

アプリを作ってみる

実際にMVVMで、テキストボックスと「=」のボタンだけの単純な『足し算アプリ』を作ってみました。

できあがりはこんな感じです。

参考までに、足し算アプリのソースコードは以下のGithubに置いています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です