バインディング宣言の概要
更新 : 2007 年 11 月
ここでは、バインディングを宣言するさまざまな方法について説明します。
このトピックには次のセクションが含まれています。
- 必要条件
- XAML でバインディングを宣言する
- コードでバインディングを作成する
- パス構文をバインドする
- 既定の動作
- 関連トピック
必要条件
このトピックを読む前に、マークアップ拡張機能の概念と使用方法を理解していることが重要です。マークアップ拡張機能の詳細については、「マークアップ拡張機能と XAML」を参照してください。
ここでは、データ バインディングの概念については説明しません。データ バインディングの概念については、「データ バインディングの概要」を参照してください。
XAML でバインディングを宣言する
ここでは、Extensible Application Markup Language (XAML) でバインディングを宣言する方法について説明します。
マークアップ拡張機能の使用方法
Binding はマークアップ拡張機能です。バインディング拡張を使用してバインディングを宣言する場合、その宣言は、Binding キーワードの後に一連の句をコンマ (,) で区切って並べたものになります。バインディング宣言では、句は任意の順序で並べることができ、また、さまざまな組み合わせが可能です。句は 名前=値 という形のペアで、名前は Binding プロパティの名前、値 はそのプロパティに設定する値です。
バインディング宣言文字列をマークアップで作成する場合、それらの文字列はターゲット オブジェクトの特定の依存関係プロパティに関連付ける必要があります。バインディング拡張を使用し、Source、Path、および UpdateSourceTrigger プロパティを指定して、TextBox.Text プロパティをバインドする方法を次の例に示します。
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=PersonName}"/>
Binding クラスのほとんどのプロパティは、この方法で指定できます。バインディング拡張の詳細、およびバインディング拡張を使用して設定できない Binding プロパティのリストについては、「バインディングのマークアップ拡張機能」の概要を参照してください。
オブジェクト要素の構文
オブジェクト要素構文を使用しても、バインディング宣言を作成できます。ほとんどの場合、マークアップ拡張機能とオブジェクト要素構文のどちらを使用した場合でも、特別な利点はありません。ただし、設定するプロパティ値が型変換のない非文字列型である場合のように、目的のシナリオがマークアップ拡張機能でサポートされない場合には、オブジェクト要素構文を使用する必要があります。
オブジェクト要素構文とマークアップ拡張機能の両方の使用方法を次の例に示します。
<TextBlock Name="myconvertedtext"
Foreground="{Binding Path=TheDate,
Converter={StaticResource MyConverterReference}}">
<TextBlock.Text>
<Binding Path="TheDate"
Converter="{StaticResource MyConverterReference}"/>
</TextBlock.Text>
</TextBlock>
この例では、拡張構文を使用してバインディングを宣言することにより、Foreground プロパティをバインドしています。Text プロパティのバインディング宣言では、オブジェクト要素構文を使用しています。
各種の用語の詳細については、「XAML 構文用語」を参照してください。
MultiBinding および PriorityBinding
MultiBinding および PriorityBinding は、XAML 拡張構文をサポートしません。そのため、XAML で MultiBinding または PriorityBinding を宣言する場合には、オブジェクト要素構文を使用する必要があります。
コードでバインディングを作成する
バインディングを指定するもう一つの方法として、コード内で Binding オブジェクトのプロパティを直接設定する方法があります。Binding オブジェクトを作成し、コードでプロパティを指定する方法を次の例に示します。
private void OnPageLoaded(object sender, EventArgs e)
{
// Make a new source, to grab a new timestamp
MyData myChangedData = new MyData();
// Create a new binding
// TheDate is a property of type DateTime on MyData class
Binding myNewBindDef = new Binding("TheDate");
myNewBindDef.Mode = BindingMode.OneWay;
myNewBindDef.Source = myChangedData;
myNewBindDef.Converter = TheConverter;
myNewBindDef.ConverterCulture = new CultureInfo("en-US");
// myDatetext is a TextBlock object that is the binding target object
BindingOperations.SetBinding(myDateText, TextBlock.TextProperty, myNewBindDef);
BindingOperations.SetBinding(myDateText, TextBlock.ForegroundProperty, myNewBindDef);
...
}
バインドする対象のオブジェクトが FrameworkElement または FrameworkContentElement の場合は、BindingOperations.SetBinding を使用する代わりに、オブジェクトで SetBinding メソッドを直接呼び出すことができます。例については、「方法 : コードでバインディングを作成する」を参照してください。
パス構文をバインドする
バインドするソースの値を指定するには、Path プロパティを使用します。
特に単純な使用例では、Path プロパティ値は Path=PropertyName など、バインディングに使用するソース オブジェクトのプロパティの名前になります。
プロパティのサブプロパティは、C# 内の構文と同様の構文によって指定できます。たとえば、Path=ShoppingCart.Order 句は、オブジェクトまたはプロパティ ShoppingCart のサブプロパティ Order へのバインディングを設定します。
添付プロパティにバインドするには、添付プロパティをかっこで囲みます。たとえば、添付プロパティ DockPanel.Dock にバインドする構文は、Path=(DockPanel.Dock) です。
プロパティのインデクサは、インデクサが適用されるプロパティ名の後に続く角かっこ内に指定できます。たとえば、Path=ShoppingCart[0] 句は、プロパティの内部のインデックスのリテラル文字列 "0" の処理方法に対応するインデックスにバインディングを設定します。入れ子になったインデクサもサポートされています。
インデクサとサブプロパティは、Path 句に混在させることができます。たとえば、Path=ShoppingCart.ShippingInfo[MailingAddress,Street] のように使用できます。
インデクサの内側では、複数のインデクサ パラメータをコンマ (,) で区切って指定できます。各パラメータの型は、かっこを使用して指定できます。たとえば、Path="[(sys:Int32)42,(sys:Int32)24]" のように指定します。ここで、sys は System 名前空間にマップされます。
ソースがコレクション ビューであるときは、現在の項目をスラッシュ (/) で指定できます。たとえば、Path=/ 句は、ビュー内の現在の項目へのバインディングを設定します。ソースがコレクションである場合、この構文は、既定のコレクション ビューの現在の項目を指定します。
プロパティ名とスラッシュを組み合わせて、コレクションである各プロパティを走査することができます。たとえば、Path=/Offices/ManagerName は、それ自体がコレクションである Offices プロパティを含む、ソース コレクションの現在の項目を指定します。その現在の項目は、ManagerName プロパティを含むオブジェクトです。
また、ピリオド (.) パスを使用して現在のソースにバインドすることもできます。たとえば、Text=?h{Binding}?h は Text=?h{Binding Path=.}?h と同じ意味です。
エスケープ機構
インデクサ ([ ]) 内では、キャレット文字 (^) は次の文字をエスケープします。
XAML でパスを指定する場合は、XML パーサーで特別な意味を持つ一定の文字についても (XML エンティティを使用して) 次のようにエスケープする必要があります。
文字 "&" をエスケープするには、& を使用します。
タグの終了を示す ">" をエスケープするには、> を使用します。
また、マークアップ拡張構文を使用して、属性内にバインディング全体を記述する場合には、WPF マークアップ拡張機能パーサーにとって特別な意味を持つ次の文字を (バックスラッシュ \ を使用して) エスケープする必要があります。
バックスラッシュ (\) は、それ自体がエスケープ文字です。
等号 (=) は、プロパティ名とプロパティ値を区切ります。
コンマ (,) は、複数のプロパティを区切ります。
右中かっこ (}) は、マークアップ拡張機能の終了を示します。
既定の動作
宣言に指定がない場合の既定の動作は次のとおりです。
バインディング ソース値とバインディング ターゲット値を相互に型変換する既定のコンバータが作成されます。型変換できない場合、既定のコンバータは null を返します。
ConverterCulture を設定しない場合、バインディング エンジンでは、バインディング ターゲット オブジェクトの Language プロパティが使用されます。XAML では、このプロパティは既定で "en-US" に設定されるか、明示的に設定されている場合はページのルート要素 (または任意の要素) から値を継承します。
バインディングに既にデータ コンテキストが存在し (たとえば、親要素から継承したデータ コンテキストの場合)、そのコンテキストから返される項目またはコレクションがすべてバインディングするために適切であり、パスを変更する必要もない場合には、バインディング宣言は、{Binding} のように、句を一切含めないで宣言することができます。これは、バインディングがコレクションに影響を与えるデータ スタイルに対してバインディングを指定する場合に多く用いられる方法です。詳細については、「バインディング ソースの概要」の「オブジェクト全体をバインディング ソースとして使用する」セクションを参照してください。
既定の Mode は、バインドされる依存関係プロパティに応じて、一方向と双方向のいずれかになります。バインディングを目的どおりに動作させるために、バインディング モードを常に明示的に宣言できます。一般に、ユーザーが編集できる TextBox.Text や RangeBase.Value などのコントロール プロパティは、既定で双方向のバインディングであり、それ以外のほとんどのプロパティは既定で一方向のバインディングになります。
既定の UpdateSourceTrigger 値も、バインドされる依存関係プロパティに応じて、PropertyChanged と LostFocus のいずれかになります。ほとんどの依存関係プロパティの既定値は PropertyChanged であるのに対し、TextBox.Text プロパティの既定値は LostFocus です。