XAML Windows 8.1 Binding 101

Das Databinding von XAML ist für mich eine sehr praktische Sache. Designtimeunterstützung, Designer Werkzeuge und asynchrone Daten. In Windows 8.1 gibt es ein paar kleine Neuerungen. Um alle abzuholen  mal ganz von vorne.

Daten

In einer Klasse, gerne auch ViewModel genannt werden Daten erstellt. In diesem VB.NET Beispiel eine einfache Eigenschaft für einen Raum.

   1:   Private _raum As Integer
   2:      <Range(1, 23)>
   3:      Public Property raum() As Integer
   4:          Get
   5:              Return _raum
   6:          End Get
   7:          Set(ByVal value As Integer)
   8:              _raum = value
   9:              onPropertyChanged()
  10:          End Set
  11:      End Property

Das es nur drei Räume gibt, sollten dieses validiert werden. Theoretisch klappt sowas in XAML mit DataAnnotations. Nicht in Windows 8.1.

Um eine Veränderung des Raums ans Userinterface bzw das gebundene Steuerelement übermitteln zu können, wird ein gemeinsames Event benötigt (PropertyChanged), das über ein Interface erzwungen wird.

   1:  Public Class listVM
   2:      Implements INotifyPropertyChanged
   3:  ....
   4:   
   5:     Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) 
Implements INotifyPropertyChanged.PropertyChanged
   6:      Public Sub onPropertyChanged(<CallerMemberName> Optional name As String = "")
   7:          RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
   8:      End Sub

Die Methode on… ist selbst geschrieben und erleichert das feuern (raise) des Events. In früheren XAML Versionen (Kleiner 4) musste man den Propertynamen direkt mit angeben. Das löst nun der Compiler mit dem CallerMemberName.

In der XAML Seite wird das Viewmodel deklarativ instanziert

   1:      <Page.DataContext>
   2:          <local:listVM/>
   3:      </Page.DataContext>

 

und steht dann mit seinen Eigenschaften zum Binden bereit. Beim obigen deklarieren können auch gleichzeitig Werte per Attribut ala raum=3 vorbelegt werden.

   1:      <TextBox  Text="{Binding raum,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

Mit dem Schlüsselwort Binding wird díe zuweisung Klasse Eigenscaft zu Steuerelement Eigenschaft eingeleitet. Es gibt eine alternative Syntax mit Path=. Um Änderungen in beide Richtungen zu erhalten (jemand anders ändert den Raum) wird Mode=TwoWay gewählt.

Neu hinzugekommen ist die Eigenschaft Updatesourcetrigger. Wenn diese fehlt, wird der Update bei Lostfocus ausgeführt. In diesem Beispiel sofort beim tippen jeder einzelnen Zahl. Dritte Möglichkeit ist Explizites Updaten nur auf Befehl.

   1:  Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
   2:          Dim expression = txtNummer.GetBindingExpression(TextBox.TextProperty)
   3:          expression.UpdateSource()
   4:  End Sub

Visual Studio 2013 Intellisense ist beim Binding eine echte Stütze

image

Wenn die gebundene Eigenschaft nicht vorhanden ist, was bei dynamischen Daten auch Feature ist, kann man mit dem neuen Attribut FallBackValue arbeiten. Hier wird an das nicht vorhanden Property Raum1 gebunden.

image

Falls die Daten noch nicht gefüllt sind, weil z.B. asynchron ein Service verarbeitet wird, nimmt man das Binding Attribut TargetNullValue.

Obwohl System.ComponentModel.DataAnnotations vorhanden ist und es ein Interface INotifyDataErrorInfo, fehlt eine Validierung die per Deklaration  zb ValidatesOnNotifyDataErrors  funktioniert. Es gibt natürlich wie immer mehrere Toolkits, die sich derer annehmen (XAML Toolkit, PRISM…).

Ein weiteres wichtiges Attribut behandelt die Datentypen. Per Converter und dazu gehöriger Klasse wird aus den Daten der Typ der letztendlich an ein UI Property gebdunden werden kann. Dazu aber in einem späteren Blog Post mehr.

Kommentare sind geschlossen