読者です 読者をやめる 読者になる 読者になる

銀の光と碧い空

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

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

C# WindowsPhone MvvmCross

MvvmCross シリーズの2回目は ValueConverters です。実はこの Tutorial を見つつ、自分のプロジェクトに同じ機能を追加する方針で進めているのですが、N=1 のIoC (DIコンテナ、依存性注入)の部分はプラットフォーム依存のコードを記述するところであわせて説明しようかと思います。また N=2と3はListの表示なのですが、Windows Phoneだと特に変わりないの省略します。

ValueConverters というのは、Windows Phoneでは Windows Phone のデータ バインディング に出てくる値コンバーターのことで、IValueConverter インターフェイス (System.Windows.Data) を実装して設定するものです。たとえば、ViewModel クラスの DateTime 型のプロパティを特定の書式で表現した文字列にコンバートしてView側に表示するときに値コンバーターが使えます。

Windows Phone(および他のXAMLプラットフォーム)では、IValueConverter を実装したクラスを値コンバーターに指定していましたが、MvvmCross ではプラットフォーム共通にするために PCLなCoreプロジェクトでプラットフォーム共通な ValueConverter クラスを定義し、各プラットフォーム固有のプロジェクトでそれをプラットフォームごとの実装に変換する仕掛けを入れます。

なお、このTutorialの解説ブログ記事にて、「ViewModel はよりView に密接であるべきで、 Converter を使わずにViewModelにViewが必要とするプロパティを記述するべき(上の例では、DateTime型のプロパティではなく、表示する書式の文字列を持ったstring型のプロパティをViewModelに持たせるべき)」という意見があることは理解していると注釈が入っています。

Forwards: N=4: ValueConverters (N+1 days of MvvmCross)

確かに私もあまり値コンバーターは使わずViewModelに直接プロパティを作っていました。が、ViewModelを共通化するためには ValueConverter を使用していかざるを得ない場面もありそうです。

それでは、実際の使い方を説明します。

CoreプロジェクトにValueConverterクラスを作る

それでは、Core プロジェクトにプラットフォーム共有のValueConverterクラスを作ります。Converters フォルダ以下に、今回のサンプルとして、DateTime を文字列にフォーマットする、 Iso8601Converter を作成します。

Cirrious.CrossCore.Converters.MvxValueConverter<TFrom, TTo> を継承したクラスにして、Convertメソッドをoverrideします(逆向きのコンバートを定義する場合は、ConvertBack メソッドもoverride)。ValueConverter の追加はこれで終わりですが、サンプルを動かすために次のようなViewModelを用意しておきます。

WP プロジェクトで Converterクラスを定義する

ここからはWindows Phoneプロジェクト側で作業します。先ほど書いたように、Coreプロジェクトで定義したValueConverterクラスは、プラットフォーム共通なので、WindowsPhoneの値コンバーターのクラスとしては使えません。そこでWindows Phone用に変換するのですが、Cirrious.CrossCore.WindowsPhone.Converters.MvxNativeValueConverter を継承したクラスを定義すればOKです。このとき型パラメーターTにはCoreプロジェクトで定義したValueConverterクラスを指定します。

これだけでOKです。

さて、これはこれで使えるのですが、値コンバーターといえば、boolをVisibilityに変換したりするのがXAML界隈では定番ではないでしょうか。ただ、VisibilityはWindows Phone(というかXAML)固有のクラスになってしまいます*1。そういうときのために、MvvmCross では Pluginという形式で Visibility の値コンバーターを提供しています。Plugin はプラットフォーム固有の機能を提供する手段でもあるのですが、これについての詳細はまた改めて記事にします。

今回は、ひとまず、 MvvmCross.HotTuna.Plugin.Visibility と MvvmCross.HotTuna.Plugin.Color をNugetからインストールします。そして、以下の2つのクラスを追加します。

これで値コンバーターは定義できたので、サンプルを動かすためにXAMLを書いてみます。 まずは、App.xaml にリソースを定義します。

そして、MainView.xaml でViewを定義します。

これで実行すると、日時がISO8601 形式で表示されていることと、チェックボックスのチェックをON/OFFすると、正方形のVisibilityが切り替わること、その正方形の色がViewModelで指定した色になっていることがわかると思います。

f:id:tanaka733:20140103232943p:plain

f:id:tanaka733:20140103233001p:plain

*1:AndroidとiOS側のクラスライブラリ見ていないのですが、おそらく