複数項目をまとめて、1つの場所に表示したいときに使えるMultiBindingというものがあるらしい。
今まで名前しか知らなかったし、簡単なサンプルを組んでる限り必要性を感じなかった代物です。
まぁ、あるんだし使ってみよう。
MultiBindingは、IMultiValueConverterと組み合わせて使う。
IMultiValueConverterは、IValueConverterの複数の値版になってる。ConvertとConvertBackメソッドのシグネチャは下のような感じだ。
object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
例としてintの値2つをカンマ区切りの文字列に相互変換するIMultiValueConverterの実装は下のようになる。
using System;
using System.Windows.Data;
namespace WpfMultiBindingSample
{
public class IntArrayToStringConverter : IMultiValueConverter
{
// [10,20] -> "10,20"
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int x = (int)values[0];
int y = (int)values[1];
return string.Format("{0},{1}", x, y);
}
// "10,20" -> [10,20]
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
string text = value.ToString();
string[] values = text.Split(',');
return new object[] { int.Parse(values[0]), int.Parse(values[1]) };
}
}
}
これを実際に使ってみよう。int型のプロパティを2つ持つMyPointクラスを定義してみた。
namespace WpfMultiBindingSample
{
public class MyPoint
{
public int X { get; set; }
public int Y { get; set; }
}
}
コンバータとMyPointをWindow.Resourcesに登録して、MyPointはWindow.DataContextに設定する。
<Window x:Class="WpfMultiBindingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfMultiBindingSample"
Title="Window1" Height="300" Width="300" DataContext="{DynamicResource myPoint}">
<Window.Resources>
<local:MyPoint x:Key="myPoint" X="10" Y="20" />
<local:IntArrayToStringConverter x:Key="myConverter" />
</Window.Resources>
</Window>
プロパティには、適当に10と20を設定しておいた。さて、このMyPointをTextBoxのTextにバインドしてみようと思う。単純なBindingだとTextBoxを2つ用意して各々XとYプロパティを表示する形になるけど、MultiBindingを使えば1つのTextBoxにXとYプロパティをバインドできる。
そのとき、どのような形で表示するかをConverterプロパティで指定出来る。早速さっき作ったConverterの使いどころだ。
<Window x:Class="WpfMultiBindingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfMultiBindingSample"
Title="Window1" Height="300" Width="300" DataContext="{DynamicResource myPoint}">
<Window.Resources>
<local:MyPoint x:Key="myPoint" X="10" Y="20" />
<local:IntArrayToStringConverter x:Key="myConverter" />
</Window.Resources>
<StackPanel>
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="X" />
<Binding Path="Y" />
</MultiBinding>
</TextBox.Text>
</TextBox>
<Button Content="Click" Click="Button_Click" />
</StackPanel>
</Window>
Button_Clickでは、myPointの値をMessageBoxで表示するようにしてみた。これで編集結果がちゃんと反映されているか確認できるって寸法だ。
using System.Windows;
namespace WpfMultiBindingSample
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var myPoint = (MyPoint)FindResource("myPoint");
MessageBox.Show(string.Format("({0},{1})", myPoint.X, myPoint.Y));
}
}
}
早速実行!!実行直後はTextBoxに10,20と表示されている。
これを100,40に書き換えてボタンをぽちっとな。
ばっちり!!