次の方法で共有


バインド宣言とは何ですか?

通常、開発者は、データをバインドする UI 要素の XAML マークアップでバインドを直接宣言します。 ただし、コードでバインドを宣言することもできます。 この記事では、XAML とコードの両方でバインドを宣言する方法について説明します。

[前提条件]

この記事を読む前に、マークアップ拡張機能の概念と使用方法を理解していることが重要です。 マークアップ拡張機能の詳細については、「 マークアップ拡張機能と WPF XAML」を参照してください。

この記事では、データ バインディングの概念については説明しません。 データ バインディングの概念の詳細については、「 データ バインディングの概要」を参照してください。

XAML でバインドを宣言する

Binding はマークアップ拡張機能です。 バインド拡張機能を使用してバインディングを宣言する場合、宣言は、 Binding キーワードに続く一連の句で構成され、コンマ (,) で区切られます。 バインディング宣言の句は任意の順序で指定でき、多くの組み合わせが可能です。 句は Name=Value ペアです。 NameBinding プロパティの名前で 、Value はプロパティに設定する値です。

マークアップでバインド宣言文字列を作成するときは、ターゲット オブジェクトの特定の依存関係プロパティに関連付ける必要があります。 次の例では、バインド拡張機能を使用して TextBox.Text プロパティをバインドし、 Source プロパティと Path プロパティを指定する方法を示します。

<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>

前の例では、 Personの単純なデータ オブジェクト型を使用しています。 次のスニペットは、そのオブジェクトのコードです。

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

この方法では、 Binding クラスのほとんどのプロパティを指定できます。 バインド拡張機能の詳細と、バインド拡張機能を使用して設定できない Binding プロパティの一覧については、「 バインディング マークアップ拡張機能 (.NET Framework)」 の概要を参照してください。

XAML でバインドを作成する例については、「 データ バインディングを作成する方法」を参照してください。

オブジェクト要素の構文

オブジェクト要素の構文は、バインディング宣言を作成する代わりに使用します。 ほとんどの場合、マークアップ拡張またはオブジェクト要素構文を使用しても特に利点はありません。 ただし、プロパティ値が型変換が存在しない文字列以外の型である場合など、マークアップ拡張機能がシナリオをサポートしていない場合は、オブジェクト要素の構文を使用する必要があります。

前のセクションでは、XAML 拡張機能を使用してバインドする方法を示しました。 次の例は、同じバインディングを実行するが、オブジェクト要素の構文を使用する方法を示しています。

<TextBlock>
    <TextBlock.Text>
        <Binding Source="{StaticResource myDataSource}" Path="Name"/>
    </TextBlock.Text>
</TextBlock>

さまざまな用語の詳細については、「 XAML 構文の詳細 (.NET Framework)」を参照してください。

MultiBinding と PriorityBinding

MultiBinding および PriorityBinding は XAML 拡張構文をサポートしていません。 そのため、XAML で MultiBinding または PriorityBinding を宣言する場合は、オブジェクト要素の構文を使用する必要があります。

コードでバインドを作成する

バインドを指定するもう 1 つの方法は、コード内の Binding オブジェクトにプロパティを直接設定し、そのバインドをプロパティに割り当てることです。 次の例は、コードで Binding オブジェクトを作成する方法を示しています。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Make a new data source object
    var personDetails = new Person()
    {
        Name = "John",
        Birthdate = DateTime.Parse("2001-02-03")
    };

    // New binding object using the path of 'Name' for whatever source object is used
    var nameBindingObject = new Binding("Name");

    // Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay;
    nameBindingObject.Source = personDetails;
    nameBindingObject.Converter = NameConverter.Instance;
    nameBindingObject.ConverterCulture = new CultureInfo("en-US");

    // Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)

    ' Make a new data source object
    Dim personDetails As New Person() With {
        .Name = "John",
        .Birthdate = Date.Parse("2001-02-03")
    }

    ' New binding object using the path of 'Name' for whatever source object is used
    Dim nameBindingObject As New Binding("Name")

    ' Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay
    nameBindingObject.Source = personDetails
    nameBindingObject.Converter = NameConverter.Instance
    nameBindingObject.ConverterCulture = New CultureInfo("en-US")

    ' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)

End Sub

前のコードでは、バインディングに次のコードが設定されています。

  • データ ソース オブジェクトのプロパティのパス。
  • バインディングのモード。
  • データ ソース (この場合は、人物を表す単純なオブジェクト インスタンス)。
  • ターゲット プロパティに割り当てられる前に、データ ソース オブジェクトから入ってくる値を処理するオプションのコンバーター。

バインドするオブジェクトがFrameworkElementまたはFrameworkContentElementの場合は、SetBindingを使用する代わりに、オブジェクトに対して直接BindingOperations.SetBinding メソッドを呼び出すことができます。 例については、「 方法: コードでバインドを作成する」を参照してください。

前の例では、 Personの単純なデータ オブジェクト型を使用しています。 そのオブジェクトのコードを次に示します。

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

バインディング パスの構文

バインド先のソース値を指定するには、 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]"を持ち、sysSystem名前空間にマップされることができます。

  • ソースがコレクション ビューの場合、現在の項目はスラッシュ (/) で指定できます。 たとえば、 Path=/ 句は、ビュー内の現在の項目にバインドを設定します。 ソースがコレクションの場合、この構文は既定のコレクション ビューの現在の項目を指定します。

  • プロパティ名とスラッシュを組み合わせて使用することで、コレクションであるプロパティにアクセスすることができます。 たとえば、 Path=/Offices/ManagerName は、コレクションでもある Offices プロパティを含むソース コレクションの現在の項目を指定します。 現在の項目は、 ManagerName プロパティを含むオブジェクトです。

  • 必要に応じて、ピリオド (.) パスを使用して現在のソースにバインドできます。 たとえば、Text="{Binding}"Text="{Binding Path=.}"と同じです。

エスケープメカニズム

  • インデクサー ([ ]) 内では、キャレット文字 (^) は次の文字をエスケープします。

  • XAML で Path を設定する場合は、XML 言語定義に特殊な特定の文字をエスケープ (XML エンティティを使用) する必要もあります。

    • &amp;を使用して文字 "&" をエスケープします。

    • 終了タグ "&gt;" をエスケープするには、>を使用します。

  • さらに、マークアップ拡張構文を使用して属性のバインド全体を記述する場合は、WPF マークアップ拡張パーサーに特別な文字 (円記号 \を使用) をエスケープする必要があります。

    • バックスラッシュ (\) はエスケープ文字自体です。

    • 等号 (=) は、プロパティ名とプロパティ値を区切ります。

    • コンマ (,) はプロパティを区切ります。

    • 右中かっこ (}) は、マークアップ拡張の末尾です。

バインディング方向

バインドの方向を指定するには、 Binding.Mode プロパティを使用します。 次のモードは、更新プログラムのバインドに使用できるオプションです。

バインディング モード 説明
BindingMode.TwoWay ターゲット プロパティまたはソース プロパティが変更されるたびに、ターゲット プロパティまたはプロパティを更新します。
BindingMode.OneWay ソース プロパティが変更された場合にのみ、ターゲット プロパティを更新します。
BindingMode.OneTime アプリケーションが起動したとき、または DataContext が変更を受けた場合にのみ、ターゲット プロパティを更新します。
BindingMode.OneWayToSource ターゲット プロパティが変更されたときにソース プロパティを更新します。
BindingMode.Default ターゲット プロパティの既定の Mode 値を使用します。

詳細については、BindingMode 列挙型を参照してください。

次の例は、 Mode プロパティを設定する方法を示しています。

<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />

ソースの変更 (OneWay バインドと TwoWay バインディングに適用可能) を検出するには、ソースで適切なプロパティ変更通知メカニズム (INotifyPropertyChangedなど) を実装する必要があります。 詳細については、「 変更通知の提供」を参照してください。

TwoWay バインドまたは OneWayToSource バインドの場合は、UpdateSourceTrigger プロパティを設定することで、ソースの更新のタイミングを制御できます。 詳細については、UpdateSourceTriggerを参照してください。

既定の動作

宣言で指定されていない場合、既定の動作は次のようになります。

  • バインディング ソース値とバインディング ターゲット値の間で型変換を実行する既定のコンバーターが作成されます。 変換できない場合、既定のコンバーターは nullを返します。

  • ConverterCulture設定しない場合、バインド エンジンはバインディング ターゲット オブジェクトのLanguageプロパティを使用します。 XAML では、これが既定で en-US されるか、ページのルート要素 (または任意の要素) から値が継承されます (明示的に設定されている場合)。

  • バインディングにデータ コンテキスト (親要素から継承されたデータ コンテキストなど) が既に存在し、そのコンテキストによって返される項目またはコレクションが、さらにパスを変更せずにバインドに適している限り、バインディング宣言には句をまったく含めなくなります: {Binding}。 これは、バインディングがコレクションに作用するデータスタイルの設定方法を指定するための一般的な方法です。 詳細については、「 オブジェクト全体をバインディング ソースとして使用する」を参照してください。

  • 既定の Mode は、バインドされている依存関係プロパティによって一方向と双方向の間で異なります。 バインド モードを明示的に宣言して、バインディングが目的の動作を持っていることを確認できます。 一般に、 TextBox.TextRangeBase.Valueなどのユーザーが編集可能なコントロール プロパティは、既定では双方向バインディングですが、他のほとんどのプロパティは一方向バインドに既定で設定されます。

  • 既定の UpdateSourceTrigger 値は、バインドされた依存関係プロパティにも応じて、 PropertyChangedLostFocus によって異なります。 ほとんどの依存関係プロパティの既定値は PropertyChangedですが、 TextBox.Text プロパティの既定値は LostFocus です。

こちらも参照ください