4つのアーキテクチャ
Windows Template Studioウィザードの2番目の画面で、デザインパターンを選びました(次の画像)。前のサンプルアプリでは[Code Behind]を選び、画面のコードビハインドにイベントハンドラーを書きました。そのイベントハンドラーの中でロジックを呼び出すコードを書いていましたから、画面とロジックが深く結びついていたわけです。選択肢の残りの4つはいずれも、画面(=View)とロジック(=Model)を分離するためのアーキテクチャです。
- MVVM Light:MVVMパターン。UWP/WPF/Xamarin[C#/VB]
- MVVM Basic:MVVMパターン。UWP[C#/VB]
- Caliburn.Micro:MVVMパターン/MVPパターン/MVCパターン。UWP/WPF[C#]
- Prism:MVVMパターン。UWP/WPF/Xamarin[C#]
MVVM Lightの例
MVVMパターンというと身構えてしまう人が多いかもしれません。「画面ひとつ追加するだけで、いくつもファイルを作って、くっつけるコードを書かなきゃいけないし。コマンドを書くのも面倒だし……」。
お忘れでしょうか? 前に説明したように、プロジェクトの右クリックからWindows Template Studioのページが追加できることを。MVVMパターンのプロジェクトでもそれは同じで、ページ(=View)だけでなくView Modelのソースファイルも生成してくれます。さらに、ViewとView Modelをくっつけるコードも追加してくれます。また、4つのどのフレームワークでも、コマンドを簡単に作れる仕掛けが用意されています。
2つ目のサンプルコードはMVVM Lightを使っています。自動生成されたMainページにUIとコマンドを追加する例を紹介します。
前のサンプルコードと同じように[Blankページ]を選んでMainページにしました。MVVM Lightを選んでプロジェクトを作ると、MainPage.xaml/MainPage.xaml.csの他に、View ModelであるMainViewModel.csも生成されます。これらに、前と同じように、トースト通知を出す機能を追加してみましょう。
View Modelを修正する
View Modelとは、抽象化した画面です。作ろうとしている画面はどんな機能を持っているでしょう? トースト文字列の入出力(ユーザーからの入力とユーザーへの提示)、それと、(ユーザーからの指示によって)トースト通知を出すコマンドを持っています。
トースト文字列の入出力は、読み書き可能で変化があったときにはPropertyChangedイベントを発行するプロパティとして表現できます。トースト通知を出すコマンドは、MVVM LightのRelayCommandクラスで簡単に表せます。View Modelは、次のコードのようになります。
public class MainViewModel : ViewModelBase { // bw: トーストに表示する文字列(テキストボックスに2ウェイでバインド) private string _toastMessage = "トースト通知の機能を使ってみた"; public string ToastMessage { get => _toastMessage; set => Set(ref _toastMessage, value); } // bw: トースト通知を出すコマンド(ボタンにバインド) private ICommand _showToastCommand; public ICommand ShowToastCommand { get { if (_showToastCommand == null) { _showToastCommand = new RelayCommand(() => { Singleton<ToastNotificationsService>.Instance .ShowToastNotificationSample(ToastMessage); }); } return _showToastCommand; } } public MainViewModel() { } }
ここで、プロパティのセッターから呼び出しているSetメソッドは、親クラスのViewModelBaseにあって、private変数に値をセットするとともにPropertyChangedイベントを発火してくれます。RelayCommandは、コンストラクター引数に、実行したい処理を渡すだけです(CanExecuteのON/OFFをしたい場合は第2引数を使います)。
Modelを修正する
上のコマンドの処理で呼び出しているShowToastNotificationSampleメソッドに、このような引数を取るオーバーロードはありません。前のサンプルコードと同様に、ShowToastNotificationSampleメソッドを修正します。
Viewを修正する
ViewにはすでにWindows Template StudioがView Modelを結び付けてくれていますから、データとコマンドをコントロールにバインドするだけです。次のコードのようにUIを追加します。
<!-- bw: トースト通知の機能を使うためのUIを追加 --> <StackPanel> <TextBox Header="トースト通知に表示する文字列" Text="{x:Bind ViewModel.ToastMessage, Mode=TwoWay}" AcceptsReturn="True" MaxHeight="150" TextWrapping="Wrap" ScrollViewer.VerticalScrollBarVisibility="Auto" /> <Button Command="{x:Bind ViewModel.ShowToastCommand}" Margin="0,5,0,0">トースト通知</Button> </StackPanel>
これで完了です。上の画像のように、テキストボックスへ入力した文字列がボタンクリックでトースト通知として表示されます。たしかにコードビハインドに直書きするよりはちょっと手間ですが、Windows Template StudioのおかげでMVVMパターンの実装がたったこれだけの作業で済んでしまうのです。複数画面にまたがって処理を行うような複雑なアプリを作るときは、ぜひMVVMパターンを導入しましょう。