This article is currently in the process of being translated into Japanese (~93% done).
The UpdateSourceTrigger property
過去の記事で、TextBoxの変更が即座にソースに返されないことがありました。それは即座ではなく、TextBoxからフォーカスが失われたときにソースが更新されました。この動作はバインディングの UpdateSourceTrigger と呼ばれるプロパティで制御されています。デフォルト値は "Default" で、これは基本的に、ソースはバインドしているプロパティに基づいて更新されることを意味します。執筆時点ではTextプロパティを除く全てのプロパティはプロパティが変化したらすぐに更新されますが (PropertyChanged)、Textプロパティは目的の要素がフォーカスを失った時に更新されます (LostFocus)。
Default は明らかに UpdateSourceTrigger のデフォルト値です。他のオプションは、PropertyChanged、 LostFocus と Explicit です。最初の2つは既に説明しました。最後のオプションは、単純に更新を手動でプッシュする必要があることを意味します。これには Binding の UpdateSource 呼び出しを使います。
この3つのオプションがどう働くかを見るため、過去の章のサンプルを更新して3つの動作を示します。
<Window x:Class="WpfTutorialSamples.DataBinding.DataContextSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataContextSample" Height="130" Width="310">
<StackPanel Margin="15">
<WrapPanel>
<TextBlock Text="Window title: " />
<TextBox Name="txtWindowTitle" Text="{Binding Title, UpdateSourceTrigger=Explicit}" Width="150" />
<Button Name="btnUpdateSource" Click="btnUpdateSource_Click" Margin="5,0" Padding="5,0">*</Button>
</WrapPanel>
<WrapPanel Margin="0,10,0,0">
<TextBlock Text="Window dimensions: " />
<TextBox Text="{Binding Width, UpdateSourceTrigger=LostFocus}" Width="50" />
<TextBlock Text=" x " />
<TextBox Text="{Binding Height, UpdateSourceTrigger=PropertyChanged}" Width="50" />
</WrapPanel>
</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfTutorialSamples.DataBinding
{
public partial class DataContextSample : Window
{
public DataContextSample()
{
InitializeComponent();
this.DataContext = this;
}
private void btnUpdateSource_Click(object sender, RoutedEventArgs e)
{
BindingExpression binding = txtWindowTitle.GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
}
}
このように、今回は3つのテキストボックスそれぞれで異なる UpdateSourceTrigger を使っています。
最初のテキストボックスは Explicit を使っています。これは基本的にマニュアルで行わない限りソースは更新されません。このため、テキストボックスの隣にボタンを設け、このコード要求に応じてソースの値を更新します。コードビハインドの中に Click ハンドラがあり、ここで2行のコードを使って、目的のコントロールからのバインディングを得、そのバインディングの UpdateSource() メソッドを呼び出しています。
二番目のテキストボックスは LostFocus を使っています。これは実質、Textバインディングのデフォルトです。ソースの値はフォーカスを失うごとに更新されます。
最後のテキストボックスは PropertyChanged を使っています。これはソースの値が結びついたプロパティが変更されるたびに更新されます。この場合は、テキストが変更されるとすぐに実行されます。
あなたのPCでサンプルを走らせて、3つのテキストボックスがどの様に違った動作をするか見てみてください。最初の値は、ボタンをクリックするまで変化しません。2番目の値はテキストボックスから離れるまでアップデートされません。3番目の値はテキストを変更するなどのキーの押し下げで自動的にアップデートされます。
まとめ
バインディングの UpdateSourceTrigger プロパティは変更された値をどの様に、いつ、ソースに返すかを制御します。しかし、WPFはこの制御をかなりうまくこなすので、絶えず更新されるUIと優れたパフォーマンスの最適な組み合わせを、大抵の場合はデフォルト値で得ることが出来ます。
プロセスをもっと制御する必要のある状況では、このプロパティは必ず役立ちますが、これは、必要とされるより頻繁にソースをアップデートしないことを確実にするだけです。もし全て制御したいのなら、Explicit を使ってアップデートを手動にすることが出来ます。しかし、これはデータバインディングの面白さを少し削いでしまいます。