TOC

This article is currently in the process of being translated into Japanese (~94% done).

Data binding:

Value conversion with IValueConverter

これまでは、送信と受信のプロパティがいつも互換性がある単純なデータバインディングを扱ってきました。しかしすぐに、一つの型の値をバインドして、それを少し違った型で表現したいという状況になるでしょう。

バリューコンバーターを使う事例

バリューコンバーターはデータバインディングで大変良く使います。主な事例は、

  • ある数値があるが、これをある方法でゼロを表示し、別の方法で数値を表示したい場合。
  • 値に基づいてチェックボックスをチェックしたいが、値が論理値ではなく、"yes" や "no" のような文字列の場合。
  • ファイルサイズをByteで持っているが、それをその大きさに合わせて、バイト、キロバイト、メガバイト、ギガバイトで表示したい場合。

これらは単純なケースですが、他にももっとあります。例えば、論理値でチェックボックスをチェックしたいが、それを反転して表示する場合、チェックボックスは値がfalseでチェックされ、trueの時はチェックされません。イメージソースのための画像を生成するためにもコンバーターを使えます。値に基づき、trueの場合はグリーンサインでfalseの場合はレッドサインのように。この可能性は無限です。

このようなケースでは、バリューコンバーターを使えます。IValueConverter を実装したこれらの小さなクラスは仲介者として動作し、送り元と送り先の間で値を翻訳します。値が送り先に届く前や、値が再び送り元に戻る前に値の変更が必要な状況では、おそらくコンバーターが必要になります。

小さなバリューコンバーターの実装

述べたように、WPFのバリューコンバーターは、IValueConverter インターフェースか、代わりに IMultiValueConverter インターフェース(説明は後ほど)を実装する必要があります。どちらのインターフェースも2つのメソッドの実装が必要なだけです。Convert() と ConvertBack() です。名前が示すように、これらのメソッドは送り先に送る値の変換と、戻ってくる値の変換に使われます。

入力として文字列を取り、BOOL値を返す簡単なコンバーターを、他と同様の方法で実装してみましょう。もしあなたがWPFの初心者でこのチュートリアルを読んでいるのなら、このサンプルで使われている概念に馴染みがないと思いますが、恐れることはありません、コードの後に説明があります。

<Window x:Class="WpfTutorialSamples.DataBinding.ConverterSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:local="clr-namespace:WpfTutorialSamples.DataBinding"
        Title="ConverterSample" Height="140" Width="250">
	<Window.Resources>
		<local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />
	</Window.Resources>
	<StackPanel Margin="10">
		<TextBox Name="txtValue" />
		<WrapPanel Margin="0,10">
			<TextBlock Text="Current value is: " />
			<TextBlock Text="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}"></TextBlock>
		</WrapPanel>
		<CheckBox IsChecked="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}" Content="Yes" />
	</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Data;

namespace WpfTutorialSamples.DataBinding
{
	public partial class ConverterSample : Window
	{
		public ConverterSample()
		{
			InitializeComponent();
		}
	}

	public class YesNoToBooleanConverter : IValueConverter
	{
		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			switch(value.ToString().ToLower())
			{
				case "yes":
				case "oui":
					return true;
				case "no":
				case "non":
					return false;
			}
			return false;
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			if(value is bool)
			{
				if((bool)value == true)
					return "yes";
				else
					return "no";
			}
			return "no";
		}
	}
}

コードビハインド

それでは、後ろに戻って、サンプルを見ていきましょう。コードビハインドファイルに YesNoToBooleanConverter という名前のコンバーターを実装しました。告知したように、2つの要求されたメソッドだけ実装しました。Convert() と ConvertBack() です。Convert() メソッドは入力 ( value パラメータ) として文字列を仮定し、それを true か false のBOOL値に、フォールバック値はfalseとして変換します。また同様に、フランス語を入力、変換するなんてこともできます。

ConvertBack() メソッドは明らかに逆の動作を行います。入力として論理値を取り、英単語の "yes" または "no" を返します。フォールバック値は "no" です。

これら2つのメソッドが取る追加のパラメータについて、疑問に思うかもしれませんが、このサンプルでは必要ありません。それらは後の章の一つで取り上げて説明します。

XAML

XAML部分では、コンバーターのインスタンスをウィンドウのリソースとして宣言するところから始めます。テキストボックスといくつかのテキストブロック、チェックボックスコントロールがあり、ここで面白い事が起こっています。テキストボックスの値をテキストブロックとチェックボックスにバインドし、Converter プロパティを使ってコンバーターの参照しています。そこでそれぞれが必要とする型に応じて文字列と論理値にうまく変換しています。

このサンプルでは、二箇所で値を変更できます。つまり、テキストボックスに "yes" を書くか(もし false にしたいならば何を書いても)、チェックボックスをチェックすることです。あなたが何をしても、テキストボックスと同じ様に、変更は他のコントロールに反映されます。

まとめ

これは、説明のため必要以上の長さになりましたが、単純なバリューコンバーターでした。次の章ではより高度な例を見ていきますが、自身のコンバーターを書く前に、目的に合ったWPFに組み込みのコンバーターを調べておきたいかもしれません。執筆時点では20以上の活用できる組み込みコンバータがあります。それらの名前を知るために、以下のリストがあなたの役に立つかもしれません。 http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!