バインディング宣言の概要
このトピックでは、バインディングを宣言するさまざまな方法について説明します。
必須コンポーネント
このトピックを読む前に、マークアップ拡張機能の概念と使用方法について理解している必要があります。 マークアップ拡張機能の詳細については、 「マークアップ拡張機能と WPF XAML」を参照してください。
このトピックでは、データ バインディングの概念については説明しません。 データ バインディングの概念の詳細については、「Data Binding Overview」を参照してください。
XAML でのバインディングの宣言
このセクションでは、XAML でバインディングを宣言する方法について説明します。
マークアップ拡張機能の使用方法
Binding はマークアップ拡張機能です。 バインディング拡張機能を使用してバインディングを宣言するとき、この宣言は、Binding
キーワードに続く一連の句で構成され、コンマ (,) で区切られます。 バインディング宣言内の句の順序は任意で、多数の組み合わせが可能です。 句は名前=値のペアで、"名前" は Binding プロパティの名前、"値" はこのプロパティに設定する値です。
マークアップでバインディング宣言文字列を作成する場合、この文字列はターゲット オブジェクトの特定の依存関係プロパティにアタッチする必要があります。 次の例では、バインディング拡張機能を使用して TextBox.Text プロパティをバインドし、Source プロパティと Path プロパティを指定する方法を示します。
<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 Syntax の詳細」を参照してください。
MultiBinding と PriorityBinding
MultiBinding と PriorityBinding では、XAML 拡張構文はサポートされていません。 したがって、XAML で MultiBinding または PriorityBinding を宣言する場合は、オブジェクト要素構文を使用する必要があります。
コードでバインディングを作成する方法
バインディングを指定する別の方法は、コードで Binding オブジェクトにプロパティを直接設定する方法です。 次の例では、Binding オブジェクトを作成し、コードでプロパティを指定する方法を示します。 この例では、TheConverter
は IValueConverter インターフェイスを実装するオブジェクトです。
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);
lbChooseCulture.SelectedIndex = 0;
}
Private Sub OnPageLoaded(ByVal sender As Object, ByVal e As EventArgs)
' Make a new source, to grab a new timestamp
Dim myChangedData As New MyData()
' Create a new binding
' TheDate is a property of type DateTime on MyData class
Dim myNewBindDef As 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)
lbChooseCulture.SelectedIndex = 0
End Sub
バインディングしているオブジェクトが FrameworkElement または FrameworkContentElement の場合、BindingOperations.SetBinding を使用する代わりに、オブジェクトで SetBinding
メソッドを直接呼び出すことができます。 例については、「Create a Binding in Code」を参照してください。
バインディング パス構文
Path プロパティを使用して、バインドするソース値を指定します。
最も簡単なケースでは、Path プロパティの値は、バインディングに使用するソース オブジェクトのプロパティの名前です (
Path=PropertyName
など)。プロパティのサブプロパティは、C# と同様の構文で指定できます。 たとえば、句
Path=ShoppingCart.Order
は、バインディングをオブジェクトのサブプロパティOrder
またはプロパティShoppingCart
に設定します。添付プロパティにバインドするには、添付プロパティをかっこで囲みます。 たとえば、添付プロパティ 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="{Binding}"
は、Text="{Binding Path=.}"
と同じです。
エスケープのしくみ
インデクサー ([ ]) 内では、キャレット文字 (^) は次の文字をエスケープします。
XAML で Path を設定した場合、XML 言語定義で特別な意味を持つ特定の文字も (XML エンティティを使用して) エスケープする必要があります。
「&」をエスケープするには
&
を使用します。終了タグ ">" をエスケープするには、
>
を使用します。
さらに、マークアップ拡張構文を使用して属性のバインディング全体を記述する場合、WPF マークアップ拡張機能パーサーで特別な意味を持つ文字を (円記号 \ を使用して) エスケープする必要があります。
円記号 (\) はエスケープ文字そのものです。
等号 (=) は、プロパティ名とプロパティの値を区切ります。
コンマ (,) はプロパティを区切ります。
右中かっこ (}) は、マークアップ拡張機能の終わりです。
既定の動作
既定の動作は、宣言で指定されていない場合には次のとおりです。
バインディング ソースの値とバインディング ターゲットの値の型変換を実行しようとする既定のコンバーターが作成されます。 変換を実行できない場合、既定のコンバーターは
null
を返します。ConverterCulture を設定しない場合、バインディング エンジンではバインディング ターゲット オブジェクトの
Language
プロパティが使用されます。 XAML では、既定で "en-US" になるか、または明示的に設定されている場合にはページのルート要素 (または任意の要素) から値を継承します。バインディングに既にデータ コンテキスト (たとえば、親要素から継承したデータ コンテキスト) があり、そのコンテキストによって返される項目またはコンテキストが何であれ、さらなるパスの変更を必要とせずにバインディングに対して適切である限り、バインディング宣言に句がまったくなくてもかまいません:
{Binding}
。これは、多くの場合、データのスタイルに対してバインディングを指定する方法で、バインディングはコレクションに基づいて動作します。 詳細については、「バインディング ソースの概要」の「バインディング ソースとして使用する全体オブジェクト」セクションを参照してください。既定の Mode は、バインドされている依存関係プロパティによって一方向と双方向で異なります。 常にバインディング モードを明示的に宣言し、バインディングに目的の動作があることを確認できます。 一般に、ユーザーが編集できる TextBox.Text や RangeBase.Value などのコントロール プロパティは既定で双方向のバインディングであり、それ以外のほとんどのプロパティは既定で一方向のバインドになります。
既定の UpdateSourceTrigger 値は、バインドされている依存関係プロパティによっても PropertyChanged と LostFocus で異なります。 ほとんどの依存関係プロパティの既定値は PropertyChanged です。ただし、TextBox.Text プロパティの既定値は LostFocus です。
関連項目
.NET Desktop feedback