はじめに
戒めの覚え書き その2
今回は MVVM の View 層について少し掘り下げます。
View 層に定義されるロジックは描画や表示に関わるものが基本となり、この実装をサポートするための仕組みがいくつか用意されています。ここではコンバーターについてまとめます。
前回と同じくオレオレ解釈なので、原則に沿わない面もあるかもしれません。すみません。
本文
コンバーターとはその名の通り、要素間で値を変換するための機構を指します。
具体的には ViewModel のプロパティがそのままでは View にバインドできない場合に、両者の間を取り持つ存在です。コンバーターがあることによって、ViewModel の描画に対する意識を削ぐことができ、View は任意の値を描画に適した形へと柔軟に変換できます。
例えば ViewMoidel の bool 型プロパティで View の要素の Visibility を制御する場合、双方の型が異なるため直接バインドすることは出来ません。
private bool _isVisible;
public bool IsVisible
{
get => this._isVisible;
set => this.SetProperty(ref this._isVisible, value);
}
<!-- これができない -->
<GroupBox Visibility="{Binding IsVisible, Mode=TwoWay}"/>
そこで以下のような IValueConverter インターフェースを実装したクラスを作成し、双方向の変換に必要なロジックを実装します。これを View のリソースに定義し、先の画面要素の Binding.Converter プロパティに設定することで、作成したコンバーターが間に入りバインドが実現されます。
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> value is bool isVisible && isVisible ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> value is Visibility visibility && visibility == Visibility.Visible;
}
<Window.Resources>
<c:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<!-- Converter によってバインドが実現する -->
<GroupBox Visibility="{Binding IsVisible, Mode=TwoWay, Converter={StaticResource BooleanToVisibilityConverter}}"/>
※ちなみに、この例で挙げた bool 値を Visibility に変換するコンバーターは、定義済みのクラスで System.Windows.Controls.BooleanToVisibilityConverter として存在します。数は少ないですが、必要な変換を行うコンバーターが存在するなら、それを利用する方が確かでしょう。
おわりに
コンバーターを使えば実装上で求められる様々な値の変換に対応することができます。View は ViewModel のプロパティを都合の良い型でマッピングできるようになり、ビジネスロジックは独立性が高まります。
ですが実際は、そこまで複雑な変換ロジックを要求される場面は少なく、bool 値の変換などの単純処理でいちいちコンバーターを定義するのは面倒に感じます。次回はこれを解決する非常に強力で汎用性の高いライブラリ QuickConverter についてご紹介します。