オルタナティブ・ブログ > IT's my business >

IT業界のコメントマニアが始めるブログ。いつまで続くのか?

(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を使って複数の対象をまとめてバインディングできます。プロパティ要素構文を使っているという点を除けば、この中のバインディング指定は通常のバインディングと同じです。

Xaml12

Comment(0)