Zusammenfassung von Kapitel 16. Datenbindung
Hinweis
Dieses Buch wurde im Frühjahr 2016 veröffentlicht und seitdem nicht aktualisiert. Wenngleich ein großer Teil des Buchs weiterhin relevante Informationen liefert, sind einige Abschnitte veraltet, und einige Themen sind nicht mehr korrekt oder vollständig.
Programmierer müssen oft Ereignishandler schreiben, die erkennen, wenn sich eine Eigenschaft eines Objekts geändert hat, und dies nutzen, um den Wert einer Eigenschaft in einem anderen Objekt zu ändern. Dieser Prozess kann mithilfe einer Datenbindung genannten Technik automatisiert werden. Datenbindungen werden in der Regel in XAML definiert und Teil der Definition der Benutzeroberfläche.
Sehr oft verbinden diese Datenbindungen Benutzeroberflächenobjekte mit zugrunde liegenden Daten. Dies ist eine Technik, die in Kapitel 18 genauer untersucht wird. MVVM. Datenbindungen können jedoch auch zwei oder mehr Benutzeroberflächenelemente verbinden. In den meisten der frühen Beispiele für Datenbindung in diesem Kapitel wird diese Technik veranschaulicht.
Grundlagen der Datenbindung
An der Datenbindung sind mehrere Eigenschaften, Methoden und Klassen beteiligt:
- Die Klasse
Binding
leitet sich vonBindingBase
ab und kapselt viele Merkmale einer Datenbindung. - Die Eigenschaft
BindingContext
wird von der KlasseBindableObject
definiert. - Die Methode
SetBinding
wird auch von der KlasseBindableObject
definiert. - Die Klasse
BindableObjectExtensions
definiert drei weitereSetBinding
-Methoden.
Die beiden folgenden Klassen unterstützen XAML-Markuperweiterungen für Bindungen:
BindingExtension
unterstützt die MarkuperweiterungBinding
.ReferenceExtension
unterstützt die Markuperweiterungx:Reference
.
An der Datenbindung sind zwei Schnittstellen beteiligt:
INotifyPropertyChanged
im NamespaceSystem.ComponentModel
dient der Implementierung der Benachrichtigung bei Änderung einer Eigenschaft.IValueConverter
dient zur Definition kleiner Klassen, die in Datenbindungen Werte von einem Typ in einen anderen konvertieren.
Eine Datenbindung verbindet zwei Eigenschaften desselben Objekts oder (häufiger) zwei verschiedene Objekte. Diese beiden Eigenschaften werden als Quelle und Ziel bezeichnet. Im Allgemeinen bewirkt eine Änderung der Quelleigenschaft eine Änderung der Zieleigenschaft, doch mitunter wird die Richtung umgekehrt. Stets gilt jedoch:
- Die Zieleigenschaft muss von
BindableProperty
unterstützt werden. - Die Quelleigenschaft ist im Allgemeinen ein Member einer Klasse, die
INotifyPropertyChanged
implementiert.
Eine Klasse, die INotifyPropertyChanged
implementiert, löst das Ereignis PropertyChanged
aus, sobald eine Eigenschaft ihren Wert ändert. BindableObject
implementiert INotifyPropertyChanged
und löst automatisch das Ereignis PropertyChanged
aus, wenn eine durch BindableProperty
unterstützte Eigenschaft Werte ändert. Sie können jedoch eigene Klassen schreiben, die INotifyPropertyChanged
ohne Ableitung von BindableObject
implementieren.
Code und XAML
Das Beispiel OpacityBindingCode zeigt, wie eine Datenbindung im Code festgelegt werden kann:
- Die Quelle ist die
Value
-Eigenschaft einesSlider
-Objekts. - Das Ziel ist die
Opacity
-Eigenschaft einesLabel
-Objekts.
Die beiden Objekte werden durch Festlegen von BindingContext
des Label
-Objekts mit dem Slider
-Objekt verbunden. Die beiden Eigenschaften werden durch den Aufruf der Erweiterungsmethode SetBinding
für das Label
-Objekt verbunden. Dabei wird auf die bindbare Eigenschaft OpacityProperty
und die Value
-Eigenschaft des Slider
-Objekts, ausgedrückt als Zeichenfolge, verwiesen.
Wenn Sie das Slider
-Objekt bearbeiten, wird das Label
-Objekt aus der Ansicht ausgeblendet.
OpacityBindingXaml ist dasselbe Programm, bei dem die Datenbindung in XAML festgelegt ist. BindingContext
des Label
-Objekts wird auf die Markuperweiterung x:Reference
festgelegt, die auf Slider
verweist. Die Eigenschaft Opacity
des Label
-Objekts wird auf die Markuperweiterung Binding
festgelegt, wobei die Eigenschaft Path
auf die Value
-Eigenschaft von Slider
verweist.
Quelle und BindingContext
Das Beispiel BindingSourceCode zeigt einen alternativen Ansatz im Code. Ein Binding
-Objekt wird erstellt, indem die Source
-Eigenschaft auf das Slider
-Objekt und die Path
-Eigenschaft auf „Wert“ festgelegt wird. Die SetBinding
-Methode von BindableObject
wird dann für das Label
-Objekt aufgerufen.
Der Binding
-Konstruktor kann auch zum Definieren des Binding
-Objekts verwendet werden.
Das Beispiel BindingSourceXaml zeigt die vergleichbare Technik in XAML. Die Opacity
-Eigenschaft von Label
wird auf die Markuperweiterung Binding
festgelegt, wobei Path
auf die Value
-Eigenschaft und Source
auf die eingebettete Markuperweiterung x:Reference
festgelegt wird.
Zusammenfassend gibt es zwei Möglichkeiten, auf das Bindungsquellobjekt zu verweisen:
- Über die
BindingContext
-Eigenschaft des Ziels - Über die
Source
-Eigenschaft desBinding
-Objekts selbst
Wenn beides angegeben wird, hat die zweite Vorrang. Der Vorteil von BindingContext
besteht darin, dass die Weitergabe durch die visuelle Struktur erfolgt. Dies ist sehr praktisch, wenn mehrere Zieleigenschaften an dasselbe Quellobjekt gebunden sind.
Das Programm WebViewDemo demonstriert diese Technik mit dem Element WebView
. Zwei Button
-Elemente zur Vor- und Rückwärtsnavigation erben BindingContext
von ihrem übergeordneten Element, das auf WebView
verweist. Die IsEnabled
-Eigenschaften der beiden Schaltflächen haben dann einfache Markuperweiterungen des Typs Binding
, die auf die IsEnabled
-Eigenschaften der Schaltfläche abzielen, und zwar auf der Grundlage der Einstellungen für CanGoBack
und der schreibgeschützten CanGoForward
-Eigenschaften der WebView
.
Der Bindungsmodus
Legen Sie die Mode
-Eigenschaft von Binding
auf einen Member der BindingMode
-Enumeration fest:
OneWay
, damit sich Änderungen in der Quelleigenschaft auf das Ziel auswirken.OneWayToSource
, damit sich Änderungen in der Zieleigenschaft auf die Quelle auswirken.TwoWay
, damit sich Änderungen in Quelle und Ziel gegenseitig beeinflussen.Default
, damit derDefaultBindingMode
verwendet wird, der beim Erstellen der Ziel-BindableProperty
angegeben wurde. Wenn nichts angegeben wurde, ist der StandardOneWay
für normale bindbare Eigenschaften undOneWayToSource
für schreibgeschützte bindbare Eigenschaften.
Hinweis
Die Enumeration BindingMode
enthält nun auch OnTime
, um eine Bindung nur dann anzuwenden, wenn sich der Bindungskontext ändert, und nicht, wenn sich die Quelleigenschaft ändert.
Eigenschaften, die voraussichtlich das Ziel von Datenbindungen in MVVM-Szenarien sein werden, haben im Allgemeinen die DefaultBindingMode
-Einstellung TwoWay
. Dies sind:
- die
Value
-Eigenschaft vonSlider
undStepper
- die
IsToggled
-Eigenschaft vonSwitch
- die
Text
-Eigenschaft vonEntry
,Editor
undSearchBar
- die
Date
-Eigenschaft vonDatePicker
- die
Time
-Eigenschaft vonTimePicker
Das Beispiel BindingModes veranschaulicht die vier Bindungsmodi mit einer Datenbindung, bei der das Ziel die FontSize
-Eigenschaft eines Label
-Elements und die Quelle die Value
-Eigenschaft eines Slider
-Elements ist. Dies ermöglicht es jedem Slider
-Element, den Schriftgrad des entsprechenden Label
-Elements zu steuern. Die Slider
-Elemente werden jedoch nicht initialisiert, weil der DefaultBindingMode
der FontSize
-Eigenschaft OneWay
ist.
Das Beispiel ReverseBinding legt die Bindungen für die Value
-Eigenschaft des Slider
-Elements fest, die auf die FontSize
-Eigenschaft jedes Label
-Elements verweist. Das scheint verkehrt herum zu sein, aber es funktioniert besser bei der Initialisierung der Slider
-Elemente, weil die Value
-Eigenschaft des Slider
-Elements die DefaultBindingMode
-Einstellung TwoWay
hat.
Dies ist analog zur Definition von Bindungen in MVVM. Sie werden diese Art von Bindung häufig verwenden.
Zeichenfolgenformatierung
Wenn die Zieleigenschaft den Typ string
hat, können Sie die von BindingBase
definierte StringFormat
-Eigenschaft verwenden, um die Quelle in string
zu konvertieren. Legen Sie die StringFormat
-Eigenschaft auf eine .NET-Formatierungszeichenfolge fest, die Sie mit dem statischen Format String.Format
zum Anzeigen des Objekts verwenden. Bei Verwenden dieser Formatierungszeichenfolge innerhalb einer Markuperweiterung umgeben Sie diese mit einfachen Anführungszeichen, damit die geschweiften Klammern nicht mit einer eingebetteten Markuperweiterung verwechselt werden.
Das Beispiel ShowViewValues veranschaulicht die Verwendung von StringFormat
in XAML.
Das Beispiel WhatSizeBindings demonstriert die Darstellung der Größe der Seite mit Bindungen an die Eigenschaften Width
und Height
von ContentPage
.
Warum lautet der Name „Path“?
Die Eigenschaft Path
von Binding
wird so genannt, weil es sich um eine Reihe von Eigenschaften und Indexern handeln kann, die durch Punkte getrennt sind. Das Beispiel BindingPathDemos zeigt mehrere Beispiele.
Bindungswertkonverter
Wenn die Quell- und Zieleigenschaften einer Bindung unterschiedliche Typen sind, können Sie mit einem Bindungskonverter die Konvertierung zwischen den Typen vornehmen. Dies ist eine Klasse, die die Schnittstelle IValueConverter
implementiert und zwei Methoden enthält: Convert
zur Konvertierung der Quelle in das Ziel und ConvertBack
zur Konvertierung des Ziels in die Quelle.
Die IntToBoolConverter
-Klasse in der Bibliothek Xamarin.FormsBook.Toolkit ist ein Beispiel für das Konvertieren von int
in bool
. Dies wird durch das Beispiel ButtonEnabler veranschaulicht, das Button
nur dann aktiviert, wenn mindestens ein Zeichen in Entry
eingegeben wurde.
Die Klasse BoolToStringConverter
konvertiert bool
in string
und definiert zwei Eigenschaften, um anzugeben, welcher Text für die Werte false
und true
zurückgegeben werden soll.
BoolToColorConverter
ist ähnlich. Das Beispiel SwitchText demonstriert die Verwendung dieser beiden Konverter zur Anzeige unterschiedlicher Texte in unterschiedlichen Farben auf Grundlage einer Switch
-Einstellung.
Der generische BoolToObjectConverter
kann BoolToStringConverter
und BoolToColorConverter
ersetzen und als universeller bool
-zu-Objekt-Konverter beliebiger Typen dienen.
Bindungen und benutzerdefinierte Ansichten
Mithilfe von Datenbindungen können Sie benutzerdefinierte Steuerelemente vereinfachen. Die Codedatei NewCheckBox.cs
definiert die Eigenschaften Text
, TextColor
, FontSize
, FontAttributes
und IsChecked
, enthält jedoch keinerlei Logik für die visuelle Darstellung des Steuerelements.
Stattdessen enthält die Datei NewCheckBox.cs.xaml
das gesamte Markup für die visuellen Elemente des Steuerelements durch Datenbindungen an die Label
-Elemente, und zwar auf Grundlage der in der CodeBehind-Datei definierten Eigenschaften.
Das Beispiel NewCheckBoxDemo veranschaulicht das benutzerdefinierte Steuerelement NewCheckBox
.