(XAML#12)「データバインディングと書式指定」
WPF におけるデータバインディングは、コントロールのプロパティにさまざまなデータを結び付ける強力な機能です。そして、このバインディングにおいて書式を指定できます(初期の WPF にはありませんでした)。ここでは、string.Format メソッドで使うような .NET Framework の型の書式指定が使えます。
書式指定の例をいくつか示します。
[XAML]
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</StackPanel.Resources>
<Slider x:Name="slider1" />
<TextBlock x:Name="tblock1" Text="{Binding ElementName=slider1, Path=Value, StringFormat={}{0:N2}}" />
<TextBlock x:Name="tblock2" Text="{Binding ElementName=slider1, Path=Value, StringFormat=N2}" />
<TextBlock x:Name="tblock3" Text="{Binding Path=Now, StringFormat=yyyy年MM月dd日\ hh時mm分ss秒}" />
<TextBlock x:Name="tblock4" Text="{Binding Path=Now, StringFormat=yyyy/MM/dd hh:mm:ss}" />
<TextBlock x:Name="tblock5" Text="{Binding Path=Time, StringFormat=hh\\:mm\\:ss}" />
<TextBlock x:Name="tblock6" Text="{Binding Path=Time, StringFormat={}{0:hh\\:mm\\:ss}}" />
<TextBlock x:Name="tblock7">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="FullName" />
<Binding Path="Count" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
[コード]
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Now = DateTime.Now;
Time = Now.TimeOfDay;
FullName = "John Smith";
Count = 12345;
DataContext = this;
}
public DateTime Now { get; set; }
public TimeSpan Time { get; set; }
public string FullName { get; set; }
public int Count { get; set; }
...
1つめでは、Binding で「StringFormat={}{0:N2}」と指定しています。string.Format のような通常の書式指定では「{0:N2}」だけでよいのですが、XAML の中では「{」が {Binding} や {x:Null} のようなマークアップを意味するため、StringFormat に指定された「{」が書式指定なのかマークアップの一部なのかを区別するために直前に「{}」をつけて区別しています。2つめのように、「{」「}」なしで直接書式だけを書いても認識されます。
日時のように書式の間にスペースを空けたい場合は、書式だけを書くと間のスペースがマークアップの区切りだとみなされてしまいます。3つめのようにスペースの前に「\」を書いてエスケープするか、4つめのように最初に「{}」を書き、書式を「{」と「}」で囲んでください。
5つめと6つめの時間間隔(TimeSpan)は少し注意が必要です。日時(DateTime)では問題ないのですが、コロン(:)が特殊文字として評価されてしまうため、これもエスケープする必要があります。ただし、「\」がひとつだと単純に XAML に対して「:」を渡すことになってしまい、意味がありません。XAMLに対して「\:」を渡すためには「\\:」と「\」を重ねる必要があります。
7つめは、マルチバインディングを使った例です。Bindingの代わりにMultiBindingを使って複数の対象をまとめてバインディングできます。プロパティ要素構文を使っているという点を除けば、この中のバインディング指定は通常のバインディングと同じです。