かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

PrismでMVVM(Model View ViewModel)パターンのサポート用に用意されているクラスのまとめ

Prismがバージョン4からMVVMパターンのサポートをはじめました。どんなサポートをしてくれているのか確認してみようと思います。

ViewModelのベースクラスの提供

今までViewModelクラスを作ろうとすると自分でINotifyPropertyChangedを実装したクラスを準備する必要がありました。(http://d.hatena.ne.jp/okazuki/20100223/1266897125)
Prismでは、今までMVVMパターンで最も多く再発明されていたINotifyPropertyChangedの実装クラスを提供してくれます。

  • クラス名:Microsoft.Practices.Prism.ViewModel.NotificationObject

こいつは、RaisePropertyChangedメソッドが用意されているので、継承先では、このメソッドを使ってプロパティの通知を外部に伝えることができます。
RaisePropertyChangedメソッドは以下の3パターンが提供されています。

  • void RaisePropertyChanged(string)
    • 使い方: RaisePropertyChanged("Name");
  • void RaisePropertyChanged(params string[])
    • 使い方: RaisePropertyChanged("Name", "Age");
  • void RaisePropertyChanged(Expression>)
    • 使い方: RaisePropertyChanged(() => Name);

1つ目は一番シンプルで文字列をつかってプロパティを指定します。2つ目は、複数のプロパティの変更を通知してくれます。3つ目はラムダ式を渡すことでタイプセーフにプロパティ名を渡すことができます。

自分で実装しても大した労力じゃないですが、提供されているにこしたことはないですね。

エラー情報を保持しておいてくれるクラス

次も、ViewModelを実装する際のお助けクラスです。一般的にViewModelからViewにエラーを通知するにはIDataErrorInfoインターフェースなんかを使ったりします。(http://d.hatena.ne.jp/okazuki/20100419/1271686512)
このインターフェースを実装する際にはエラー情報を保持しておくためのIDictionaryとかを使ったりするのですが、地味に同じようなコードを書いたりします。(ちょっとめんどくさい)

これを簡略化してくれるクラスも提供されています。

  • クラス名: Microsoft.Practices.Prism.ViewModel.ErrorsContainer

Tに、エラー情報として保持させておきたい型名を指定します。IDataErrorInfoだとstring型を使うようになると思います。
ViewModelのフィールドにErrorsContainerを持たせて、ClearErrors, GetErrors, SetErrorsメソッドを使ってIDataErrorInfoなどの実装を提供します。

ViewModelからコマンドを提供する際に使用するクラス

一般的なMVVMパターンではViewModelから提供されるコマンドをView側でバインドしてViewで発生したイベントをViewModel側に伝えます。
この時に、DelegateCommandと呼ばれるICommandの実装がよく使われます。これも毎回実装するのが大変なのですがPrismで提供されています。
(自前実装の例: http://d.hatena.ne.jp/okazuki/20100223/1266897125)

  • クラス名: Microsoft.Practices.Prism.Commands.DelegateCommand

Commandに対応していないコントロールをコマンド対応にするクラス

コマンドに対応していないコントロールがあったりすると、ViewModelのコマンドと繋げるのどうやろうか・・・と悩んでしまうのですが、そんな悩みを解決してくれるクラスです。
このクラスを継承すると割と簡単にコマンドに対応していないコントロールをコマンドに対応させることができます。

  • クラス名: Microsoft.Practices.Prism.Commands.CommandBehaviorBase

便利そうですが・・・Expression Blendで任意のイベントをコマンドと結びつけるBehaviorが提供されていたりするので、こいつの存在意義は正直微妙な気がします・・・。

ViewModelからViewを操作するクラス

今年の流行語大賞にノミネートはされませんでしたが、一時期MVVMにお熱だった人たちの間で、このネタを取り上げたエントリが量産されました。Prismには、これを実現するための便利クラスも提供されています

  • クラス名: Microsoft.Practices.Prism.Interactivity.InteractionRequest.InteractionRequest
  • クラス名: Microsoft.Practices.Prism.Interactivity.InteractionRequest.Notification
  • クラス名: Microsoft.Practices.Prism.Interactivity.InteractionRequest.InteractionRequestTrigger

このクラスを組み合わせることで、ViewModelからView側に一時的に処理をやらせて、結果をViewModel側で受け取って処理をやるということを美しく?処理することができるようになります。

使用例はこちら: http://d.hatena.ne.jp/okazuki/20101011/1286777561

最後に

こんな感じでMVVMパターンのプログラムを書くときに必要そうな基本的なクラスがPrismから提供されています。
自分で作るのも悪くないですが、車輪の再発明をするのもなんなので、Prismで提供されているものを使ってみるのも悪くないと思います。
Prismだったらソースも提供されているし、上で紹介したクラスは、割とシンプルなので自分で処理を追いかけるのも、難しくないです。