Freigeben über


Was sind Bindungsdeklarationen? (WPF .NET)

In der Regel deklarieren Entwickler die Bindungen direkt im XAML-Markup der UI-Elemente, an die sie Daten binden möchten. Sie können Bindungen jedoch auch in Code deklarieren. In diesem Artikel wird beschrieben, wie Bindungen sowohl in XAML als auch in Code deklariert werden.

Voraussetzungen

Bevor Sie diesen Artikel lesen, sollten Sie mit dem Konzept und der Verwendung von Markuperweiterungen vertraut sein. Weitere Informationen über Markuperweiterungen finden Sie unter Markuperweiterungen und WPF XAML.

Dieser Artikel behandelt keine Grundlagen der Datenbindung. Eine Erörterung der Datenbindungskonzepte finden Sie in der Übersicht über die Datenbindung.

Deklarieren einer Bindung in XAML

Binding ist eine Markuperweiterung. Wenn Sie die Bindungserweiterung zum Deklarieren einer Bindung verwenden, besteht die Deklaration aus einer Reihe von Klauseln, die dem Binding-Schlüsselwort folgen und durch Kommas (,) getrennt sind. Die Klauseln in der Bindungsdeklaration können in beliebiger Reihenfolge aufgeführt sein, und es gibt zahlreiche mögliche Kombinationen. Die Klauseln sind Name=Wert-Paare, wobei Name der Name der Binding-Eigenschaft und Value der Wert ist, den Sie für die Eigenschaft festlegen.

Wenn Bindungsdeklarationszeichenfolgen im Markup erstellt werden, müssen sie an die entsprechende Abhängigkeitseigenschaft eines Zielobjekts angefügt werden. Im folgenden Beispiel wird gezeigt, wie Sie die Eigenschaft TextBox.Text mithilfe der Bindungserweiterung binden, indem Sie die Eigenschaften Source und Path angeben.

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

Im vorherigen Beispiel wird ein einfacher Datentypobjekt, und zwar Person, verwendet. Der folgende Codeschnipsel ist der Code für dieses Objekt:

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

Sie können die meisten Eigenschaften der Binding-Klasse auf diese Weise angeben. Weitere Informationen über die Bindungserweiterung sowie eine Liste mit Binding-Eigenschaften, die nicht mit der Bindungserweiterung festgelegt werden können, finden Sie in der Übersicht zur Bindungs-Markuperweiterung (.NET Framework).

Ein Beispiel zum Erstellen einer Bindung in XAML finden Sie unter Erstellen einer Datenbindung.

Objektelementsyntax

Die Objektelementsyntax stellt eine Alternative zur Erstellung der Bindungsdeklaration dar. In den meisten Fällen gibt es keinen besonderen Vorteil der Verwendung der Markuperweiterung gegenüber der Objektelementsyntax. Wenn die Markuperweiterung das von Ihnen verwendete Szenario jedoch nicht unterstützt (wenn der Eigenschaftswert zum Beispiel keine Zeichenfolge ist und keine Typkonvertierung hierfür vorhanden ist), müssen Sie die Objektelementsyntax verwenden.

Im vorherigen Abschnitt wurde gezeigt, wie eine Bindung mit einer XAML-Erweiterung hergestellt wird. Das folgende Beispiel zeigt, wie die gleiche Bindung mit Objektelementsyntax erstellt wird:

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

Weitere Informationen zu den unterschiedlichen Begriffen finden Sie unter Ausführliche Erläuterung der XAML-Syntax (.NET Framework).

MultiBinding und PriorityBinding

MultiBinding und PriorityBinding unterstützen die XAML-Erweiterungssyntax nicht. Daher müssen Sie die Objektsyntax verwenden, wenn Sie eine MultiBinding oder eine PriorityBinding in XAML deklarieren.

Erstellen einer Bindung in Code

Eine andere Möglichkeit zum Festlegen einer Bindung besteht darin, Eigenschaften direkt in einem Binding-Objekt im Code festzulegen und dann die Bindung einer Eigenschaft zuzuweisen. Das folgende Beispiel veranschaulicht das Erstellen eines Binding-Objekts in Code.

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

Der vorherige Code legt folgendes für die Bindung fest:

  • Einen Pfad der Eigenschaft im Datenquellenobjekt
  • Den Bindungsmodus
  • Die Datenquelle, in diesem Fall eine einfache Objektinstanz, die eine Person darstellt.
  • Ein optionaler Konverter, der den Wert aus dem Datenquellenobjekt verarbeitet, bevor er der Zieleigenschaft zugewiesen wird.

Wenn das Objekt, zu dem Sie das eine Bindung herstellen, ein FrameworkElement oder FrameworkContentElement ist, können Sie die Methode SetBinding direkt auf Ihrem Objekt aufrufen, anstatt BindingOperations.SetBinding verwenden. Ein Beispiel finden Sie unter Gewusst wie: Erstellen einer Bindung in Code.

Im vorherigen Beispiel wird ein einfacher Datentypobjekt, und zwar Person, verwendet. Dies ist der Code für dieses Objekt:

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

Syntax des Bindungspfads

Verwenden Sie die Path-Eigenschaft, um den Quellwert anzugeben, an den Sie binden möchten:

  • Im einfachsten Fall ist der Path-Eigenschaftswert der Name der Eigenschaft des Quellobjekts, das für die Bindung verwendet wird, beispielsweise Path=PropertyName.

  • Untergeordnete Eigenschaften einer Eigenschaft können mit einer ähnlichen Syntax wie in C# angegeben werden. So legt zum Beispiel die Klausel Path=ShoppingCart.Order die Bindung für die untergeordnete Order-Eigenschaft des Objekts oder die ShoppingCart-Eigenschaft fest.

  • Um eine angefügte Eigenschaft zu binden, schließen Sie die angefügte Eigenschaft in Klammern ein. Um beispielsweise eine Bindung an die angefügte Eigenschaft DockPanel.Dock zu erstellen, gilt folgende Syntax Path=(DockPanel.Dock).

  • Indexer einer Eigenschaft können durch eckige Klammern nach dem Namen der indizierten Eigenschaft angegeben werden. So legt zum Beispiel die Path=ShoppingCart[0]-Klausel die Bindung auf den Index fest, der der Art und Weise entspricht, wie die interne Indizierung der Eigenschaft das Zeichenfolgenliteral „0“ handhabt. Geschachtelte Indexer werden ebenfalls unterstützt.

  • Indexer und untergeordnete Eigenschaften können in einer Path-Klausel kombiniert werden, z. B. Path=ShoppingCart.ShippingInfo[MailingAddress,Street]..

  • innerhalb von Indexern. Sie können mehrere Indexerparameter nutzen, die durch Kommas (,) getrennt sind. Der Typ der einzelnen Parameter kann in Klammern angegeben werden. Sie können beispielsweise über Path="[(sys:Int32)42,(sys:Int32)24]" verfügen, wobei sys dem System-Namespace zugeordnet ist.

  • Wenn die Quelle eine Auflistungsansicht darstellt, kann das aktuelle Element mit einem Schrägstrich (/) angegeben werden. Beispielsweise legt die Klausel Path=/ die Bindung auf das aktuelle Element in der Ansicht fest. Wenn die Quelle eine Auflistung darstellt, gibt diese Syntax das aktuelle Element der Standardauflistungsansicht an.

  • Eigenschaftennamen und Schrägstriche können kombiniert werden, um Eigenschaften zu durchlaufen, die Auflistungen darstellen. Beispielsweise gibt Path=/Offices/ManagerName das aktuelle Element der Quellauflistung an, die eine Offices-Eigenschaft enthält, bei der es sich ebenfalls um eine Auflistung handelt. Bei dem aktuellen Element handelt es sich um ein Objekt, das eine ManagerName-Eigenschaft enthält.

  • Optional kann ein Pfad mit einem Punkt (.) für die Bindung an die aktuelle Quelle verwendet werden. Text="{Binding}" entspricht beispielsweise Text="{Binding Path=.}".

Verwendung von Escapezeichen

  • In Indexern ([ ]) dient das Caretzeichen (^) als Escapezeichen für das nächste Zeichen.

  • Wenn Sie Path in XAML festlegen, müssen Sie auch bestimmte Zeichen (mit XML-Entitäten), die speziell von der XML-Sprachdefinitionen verwendet werden, mit Escapezeichen versehen:

    • Verwenden Sie &amp;, um das Zeichen „&“ mit Escapezeichen zu versehen.

    • Verwenden Sie &gt;, um das Endtag „>“ mit Escapezeichen zu versehen.

  • Darüber hinaus müssen Sie, wenn Sie die gesamte Bindung in einem Attribut mit der Markuperweiterungssyntax beschreiben, Zeichen (mit einem umgekehrten Schrägstrich \) mit Escapezeichen zu versehen, die speziell vom WPF-Markuperweiterungsparser verwendet werden:

    • Der umgekehrte Schrägstrich (\) ist das eigentliche Escapezeichen.

    • Das Gleichheitszeichen (=) trennt den Eigenschaftsnamen vom Eigenschaftswert.

    • Das Komma (,) trennt Eigenschaften.

    • Die rechte geschweifte Klammer (}) gibt das Ende einer Markuperweiterung an.

Bindungsrichtung

Verwenden Sie die Binding.Mode-Eigenschaft, um die Richtung der Bindung anzugeben. Die folgenden Modi stellen die verfügbaren Optionen für Aktualisierungen von Bindungen dar:

Bindungsmodus Beschreibung
BindingMode.TwoWay Aktualisiert die Zieleigenschaft oder die Eigenschaft, wenn sich entweder die Zieleigenschaft oder die Quelleigenschaft ändert.
BindingMode.OneWay Aktualisiert die Zieleigenschaft nur, wenn sich die Quelleigenschaft ändert.
BindingMode.OneTime Aktualisiert die Zieleigenschaft nur, wenn die Anwendung startet oder wenn der DataContext eine Änderung erfährt.
BindingMode.OneWayToSource Aktualisiert die Quelleigenschaft, wenn die Zieleigenschaft geändert wird.
BindingMode.Default Bewirkt, dass der Standard-Mode-Wert der Zieleigenschaft verwendet wird.

Weitere Informationen finden Sie unter der BindingMode-Enumeration.

Im folgenden Beispiel wird das Festlegen der Mode-Eigenschaft veranschaulicht:

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

Zum Erkennen von Quelländerungen (das gilt für die OneWay-Bindung und die TwoWay-Bindung) muss die Quelle einen geeigneten Mechanismus für Benachrichtigungen bei Eigenschaftenänderungen implementieren, z. B. INotifyPropertyChanged. Weitere Informationen finden Sie unter Bereitstellen von Änderungsbenachrichtigungen.

Bei TwoWay- oder OneWayToSource-Bindungen können Sie das Timing der Quellaktualisierungen steuern, indem Sie die UpdateSourceTrigger-Eigenschaft einstellen. Weitere Informationen finden Sie unter UpdateSourceTrigger.

Standardverhalten

Das Standardverhalten ist das wie folgt angegebene Verhalten, wenn nicht anders in der Deklaration angegeben:

  • Es wird ein Standardkonverter erstellt, der versucht, eine Typkonvertierung zwischen dem Wert der Bindungsquelle und dem Wert des Bindungsziels durchzuführen. Wenn keine Konvertierung durchgeführt werden kann, gibt der Standardkonverter null zurück.

  • Wenn Sie ConverterCulture nicht festlegen, nutzt die Bindungs-Engine die Eigenschaft Language des Bindungszielobjekts. In XAML ist der Standardwert „en-US“, oder der Wert wird vom Stammelement (oder einem beliebigen Element) der Seite geerbt, wenn ein Element explizit festgelegt wurde.

  • Solange die Bindung bereits über einen Datenkontext verfügt (z. B. den übernommenen Datenkontext eines übergeordneten Elements) und das von diesem Kontext zurückgegebene Element oder die Auflistung für die Bindung geeignet ist, ohne dass eine weitere Pfadänderung notwendig ist, kann eine Bindung auch über keine Klauseln verfügen: {Binding}. Dies ist häufig der Fall, wenn eine Bindung für die Datenformatierung festgelegt wird, wobei die Bindung auf eine Auflistung angewendet wird. Weitere Informationen finden Sie unter Verwenden ganzer Objekte als Bindungsquelle.

  • Der standardmäßige Mode wechselt zwischen unidirektional und bidirektional für die gebundene Abhängigkeitseigenschaft. Sie können den Bindungsmodus immer explizit deklarieren, um sicherzustellen, dass die Bindung das gewünschte Verhalten aufweist. In der Regel haben von einem Benutzer bearbeitbare Steuerelementeigenschaften, wie etwa TextBox.Text und RangeBase.Value, standardmäßig bidirektionale Bindungen, wogegen die meisten anderen Eigenschaften standardmäßig unidirektionale Bindungen haben.

  • Der Standardwert UpdateSourceTrigger variiert auch zwischen PropertyChanged und LostFocus je nach der gebundenen Abhängigkeitseigenschaft. Der Standardwert für die meisten Abhängigkeitseigenschaften ist PropertyChanged, während die TextBox.Text-Eigenschaft den Standardwert LostFocus aufweist.

Weitere Informationen