MVVM und SelectionChanged

Mit den Expression Blend Behaviors SDK in Windows 8.1 sind nun auch komplexere Befehle im Viewmodel möglich, ohne sich groß über ein ICommand verrenken zu müssen. Das Relaycommand funktioniert ohnehin nur mit wenigen Steuerelementen die ein Command Attribut bieten.

Ein Standard Anwendungsfall ist eine Liste, egal ob als ListView, GridView oder DropDown. Eine veränderte Auswahl eines Eintrags soll im Viewmodell etwas auslösen.

Dazu wird eine gewöhnliche Mehode (hier loeschen) angelegt. Nach meinen Versuchen benötigt diese idente Methodensignatur, wie in der Code Behind Methode. In meiner Erinnerung funktionierte das in Silverlight auch mit einfachen Eventargs. Das wirft allerdings in WinRT 8.1 ein böse Laufzeitfehlermeldung.

Da die Listview eine Auswahlliste ist, wird der gewählte Eintrag den AddedItems hinzugefügt, der hier gleich wieder gelöscht wird. Durch die Oberservable Collection der Bananen verschwindet der Eintrag auch im User Interface der Windows Store App.

   1:  Public Class bananeVM
   2:      ....
   3:      Public Sub loeschen(sender As Object, args As SelectionChangedEventArgs)
   4:          If args.AddedItems.Count > 0 Then
   5:              bananen.Remove(args.AddedItems(0))
   6:          End If
   7:      
   8:      End Sub
   9:      Public Property bananen As ObservableCollection(Of banane)

Im XAML wird dann über CallMethodAction die Methode ausgeführt. Das ViewModel ist an die Page gebunden. Folglich ist das Ziel des Binding, das Viewmodel der Page.

   1:  <Page.DataContext>
   2:          <local:bananeVM/>
   3:  </Page.DataContext>
   4:   
   5:   ....
   6:      <ListView  x:Name="liste1" 
   7:              ItemsSource="{Binding bananen}"  >
   8:              <ListView.ItemTemplate>
   9:                  ...
  10:              </ListView.ItemTemplate>
  11:              <Interactivity:Interaction.Behaviors>
  12:                  <Core:EventTriggerBehavior EventName="SelectionChanged">
  13:                      <Core:CallMethodAction  MethodName="loeschen"
  14:                                              TargetObject="{Binding}" >
  15:                      </Core:CallMethodAction>
  16:                  </Core:EventTriggerBehavior>
  17:              </Interactivity:Interaction.Behaviors>

Dies ist ein gutes Beispiel für, sieht nach MVVM aus und passt trotzdem nicht ganz. Im Viewmodel gibt es mit dem Parameter SelectionChangedEventArgs einen Abhängigkeit zum Steuerelement der Sicht.

Im nächsten Schritt wird diese Abhängigkeit in der Methode entfernt. Um den Status zu halten wird dann ein Property im ViewModel benötigt das den selektierten Listeneintrag enthält.

   1:  Public Class bananeVM
   2:      Implements INotifyPropertyChanged
   3:      Public Sub loeschen()
   4:             If selectedBanane > -1 Then
   5:              bananen.RemoveAt(selectedBanane)
   6:          End If
   7:      End Sub
   8:   
   9:      Public Property selectedBanane() As Integer

Hinweis: da XAML und damit die Listview zuerst gerendert wird, entsteht einen potentielle schwer zu entdeckende Fehlerquelle im selektierten Eintrag. Dieser muss auf –1 ( z.B im Konstruktor des ViewModels) gesetzt werden, da die Liste vorerst noch leer ist.

Der XAML Teil muss dann um das Binding auf die Property erweitert werden.

   1:    <ListView  x:Name="liste1" ...
   2:  SelectedIndex="{Binding selectedBanane,Mode=TwoWay}"
Kommentare sind geschlossen