銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Mvvm Light で Windows Phoneの画面遷移をする

最近 MvvmCross ネタを続けていますが、

MvvmCross で Windows Phone アプリケーションを作る ~その1~

MvvmCross で Windows Phone アプリケーションを作る ~その2 ValueConverters ~

次回画面遷移周りをやるのに合わせて、MVVM Light ではどうしているか?をまとめておきます。

MVVM Light というのは、WPF, Silverlight, Windows Phone 7/8, Windows Store App と Microsoft系XAMLプラットフォームで利用できるMVVMライブラリで、プロジェクトテンプレートやコードスニペットなどVisual Studioまわりの機能も備えています。

MVVM Light Toolkit - Home

さて、Windows Phone での画面遷移は、基本的にはPhoneApplicationPage クラスの NavigationService プロパティを通じて行います。そして、通常WindowsPhoneのページはこのクラスを継承しています。

ただ、View側のクラスからしかこのプロパティは参照できないため、ViewModel側に画面遷移の処理を書きたいときに困ってしまいます。じゃあ、どうするか?を3パターンほど考えてみました。

App.RootFrame プロパティを使う

Mvvm Light 関係ないし、直接的なので凝った方法使う必要ないのでは?という感じの方法です。 Windows Phoneのプロジェクトを作ると、App クラスの中に RootFrame staticプロパティというのがあります。これだとViewModelに限らず、どこからでもアクセスできる上、NavigationService クラスにあるメソッド、プロパティが一通り揃っています。これを使うと画面遷移できます。

Messenger パターンを使う

ここからは、MVVM Light を使う前提で、ちょっと凝った方法を紹介します。画面遷移の処理はあくまでView側に記述して、ViewModelではView側の処理を呼び出す方法です。このとき、MvvmLightで用意されている Messenger パターンの実装が使えます。

View側、つまりPageのコンストラクタで NavigationRequest というメッセージを受け取って画面遷移する処理を登録しておき、ViewModel側ではNavigationRequestというメッセージを投げるようにします。

RealyCommand というのは、Mvvm Light のICommand 実装で、XAMLのCommandプロパティにBindingできます。*1

IoC を使ってViewModelに自前のNavigationServiceを依存性注入する

最後はやりすぎ感もありますが、依存性注入を使ってみます。画面遷移するための機能をもったINavigationService インターフェースとその実装を用意し*2、MvvmLight をインストールすると作られる ViewModelLocator クラスでDIコンテナに登録します。ViewModel側ではコンストラクタインジェクションでINavigationServiceを受け取って画面遷移を行います。

結局やっているのは最初の App.RootFrame を参照する方法と同じなので、まあ最初の方法でいい気はします。ひとつのサンプルとして見ていただければ...

最初のやり方でいいのにIoCのサンプルまで持ってきたので、MvvmCross と比べたいという意図もありました。肝心のそちらの記事は明日の予定です。

*1:MvvmLight のEventToCommandのBehavior機能で任意のUI要素のイベントにコマンドをBindingすることもできる

*2:サンプルは一部機能のみの実装