Zusammenfassung von Kapitel 19. Auflistungsansichten

Beispiel herunterladen Das Beispiel herunterladen

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.

In Xamarin.Forms sind drei Ansichten definiert, mit denen Auflistungen verwaltet und die zugehörigen Elemente angezeigt werden:

  • Picker ist eine relativ kurze Liste mit Zeichenfolgenelementen, aus denen der Benutzer ein Element auswählen kann
  • ListView ist häufig eine lange Liste mit Elementen, die normalerweise denselben Typ und dieselbe Formatierung aufweisen. Aus dieser Liste können Benutzer ebenfalls ein Element auswählen
  • TableView ist eine Auflistung von Zellen (in der Regel verschiedene Typen und Erscheinungen), mit denen Daten angezeigt und Benutzereingaben verwaltet werden können

MVVM-Anwendungen verwenden häufig ListView, um eine auswählbare Auflistung von Objekten anzuzeigen.

Programmoptionen bei Picker

Picker ist gut geeignet, wenn Sie es Benutzern ermöglichen möchten, eine Option aus einer relativ kurzen Liste von string-Elementen auszuwählen.

Die Picker-Ansicht und die Ereignisbehandlung

Im PickerDemo-Beispiel wird veranschaulicht, wie Xaml verwendet wird, um die PickerTitle Eigenschaft festzulegen und der Items Auflistung Elemente hinzuzufügenstring. Wenn der Benutzer Picker auswählt, werden die Elemente in der Items-Auflistung plattformabhängig angezeigt.

Das SelectedIndexChanged-Ereignis zeigt an, wenn der Benutzer ein Element ausgewählt hat. Der nullbasierte SelectedIndex-Eigenschaft zeigt dann das ausgewählte Element an. Wenn kein Element ausgewählt ist, SelectedIndex entspricht –1.

Sie können auch die Eigenschaft SelectedIndex verwenden, um das ausgewählte Element zu initialisieren. Diese Eigenschaft muss jedoch nach dem Füllen der Items-Auflistung festgelegt werden. In XAML bedeutet dies, dass Sie SelectedIndex wahrscheinlich mit einem Eigenschaftselement festlegen.

Datenbindung und Picker

Die SelectedIndex-Eigenschaft wird durch eine bindbare Eigenschaft gestützt, Items jedoch nicht. Daher ist die Verwendung der Datenbindung mit Picker schwierig. Eine Lösung besteht darin, die Picker in Kombination mit einem ObjectToIndexConverter wie dem in der Xamarin.FormsBibliothek Book.Toolkit verwendeten zu verwenden. Das Beispiel PickerBinding zeigt die Funktionsweise.

Hinweis

Der Xamarin.FormsPicker enthält ItemsSource jetzt Eigenschaften und SelectedItem , die die Datenbindung unterstützen. Siehe Picker.

Rendern von Daten mit ListView

ListView ist die einzige Klasse, die von der Klasse ItemsView<TVisual> abgeleitet wird, von der sie die Eigenschaften ItemsSource und ItemTemplate erbt.

ItemsSource weist den Typ IEnumerable, standardmäßig jedoch den Wert null auf und muss explizit initialisiert werden bzw. (die häufigere Vorgehensweise) mithilfe einer Datenbindung auf eine Auflistung festgelegt werden. Die Elemente in dieser Auflistung können einen beliebigen Typ aufweisen.

ListView definiert eine SelectedItem-Eigenschaft, die entweder auf eins der Elemente in der ItemsSource-Auflistung oder auf null festgelegt ist, wenn kein Element ausgewählt wird. Wenn ein neues Element ausgewählt wird, löst ListView das Ereignis ItemSelected aus.

Auflistungen und Auswahlmöglichkeiten

Im Beispiel ListViewList wird eine ListView mit 17 Color-Werten in einer List<Color>-Auflistung gefüllt. Die Elemente können ausgewählt werden, werden standardmäßig jedoch in ihren weniger schönen ToString-Darstellungen angezeigt. In verschiedenen Beispielen innerhalb dieses Kapitels wird gezeigt, wie sich diese Darstellung ändern lässt, um die Elemente in der gewünschten Form anzuzeigen.

Das Zeilentrennzeichen

Bei iOS und Android werden die Zeilen durch eine dünne Linie getrennt. Sie können dieses Verhalten über die Eigenschaften SeparatorVisibility und SeparatorColor steuern. Die Eigenschaft SeparatorVisibility weist den Typ SeparatorVisibility auf, eine Enumeration, die über zwei Member verfügt:

Datenbindung für das ausgewählte Element

Die Eigenschaft SelectedItem wird durch eine bindbare Eigenschaft gestützt und kann folglich die Quelle oder das Ziel einer Datenbindung sein. Für BindingMode ist standardmäßig OneWayToSource festgelegt, im Allgemeinen ist die Eigenschaft jedoch das Ziel einer bidirektionalen Datenbindung (insbesondere in einem MVVM-Szenario). Diese Art von Bindung wird im Beispiel ListViewArray veranschaulicht.

Die Klasse „ObservableCollection“

Im Beispiel ListViewLogger wird die Eigenschaft ItemsSource einer ListView auf eine List<DateTime>-Auflistung festgelegt. Anschließend wird fortwährend mithilfe eines Timers jede Sekunde ein neues DateTime-Objekt hinzugefügt.

ListView aktualisiert sich jedoch nicht automatisch selbst, da die List<T>-Auflistung über keinen Benachrichtigungsmechanismus verfügt, der anzeigt, wenn Elemente zur Auflistung hinzugefügt oder aus der Auflistung entfernt werden.

In einem solchen Szenario sollte stattdessen die Klasse ObservableCollection<T> verwendet werden, die im System.Collections.ObjectModel-Namespace definiert ist. Diese Klasse implementiert die INotifyCollectionChanged-Schnittstelle und löst daher ein CollectionChanged-Ereignis aus, wenn Elemente zur Auflistung hinzugefügt oder aus der Auflistung entfernt werden. Auch wenn Elemente ersetzt oder innerhalb der Auflistung verschoben werden, wird ein Ereignis ausgelöst. Wenn ListView intern erkennt, dass eine Klasse, die INotifyCollectionChanged implementiert, auf ihre Eigenschaft ItemsSource festgelegt wurde, fügt ListView einen Handler zum CollectionChanged-Ereignis hinzu und aktualisiert die Anzeige, sobald die Auflistung sich ändert.

Die Verwendung von ObservableCollection wird im Beispiel ObservableLogger veranschaulicht.

Vorlagen und Zellen

Eine ListView-Klasse zeigt die Elemente in ihrer Auflistung standardmäßig mithilfe der ToString-Methode der einzelnen Elemente an. Ein besserer Ansatz ist die Definition einer Vorlage, um die Elemente anzuzeigen.

Um mit diesem Feature zu experimentieren, können Sie die NamedColor -Klasse in der Xamarin.FormsBibliothek Book.Toolkit verwenden. Diese Klasse definiert eine statische All-Eigenschaft vom Typ IList<NamedColor> mit 141 NamedColor-Objekten, die den öffentlichen Feldern der Color-Struktur entsprechen.

Im Beispiel NaiveNamedColorList wird ItemsSource einer ListView-Klasse auf diese NamedColor.All-Eigenschaft festgelegt. Es werden jedoch nur die vollqualifizierten Klassennamen der NamedColor-Objekte angezeigt.

ListView benötigt eine Vorlage, um diese Elemente anzuzeigen. Im Code können Sie die von ItemsView<TVisual> definierte Eigenschaft ItemTemplate auf ein DataTemplate-Objekt festlegen. Verwenden Sie dazu den DataTemplate-Konstruktor, der auf eine Ableitung der Cell-Klasse verweist. Cell verfügt über fünf Ableitungen:

  • TextCell — enthält zwei Label Ansichten (konzeptionell)
  • ImageCell – fügt eine Image Ansicht hinzu. TextCell
  • EntryCell – enthält eine Entry Ansicht mit einer Label
  • SwitchCell — enthält ein Switch mit einem Label
  • ViewCell — kann beliebig View sein (wahrscheinlich mit Kindern)

Rufen Sie SetValue dann und SetBinding für das DataTemplate -Objekt auf, um den Cell Eigenschaften Werte zuzuordnen, oder um Datenbindungen für die Cell Eigenschaften festzulegen, die auf eigenschaften der Elemente in der ItemsSource Auflistung verweisen. Dies wird im Beispiel TextCellListCode veranschaulicht.

Wenn ListView alle Elemente anzeigt, wird anhand der Vorlage eine kleine visuelle Struktur erstellt. Außerdem werden zwischen dem Element und den Eigenschaften der Elemente in dieser visuellen Struktur Datenbindungen erstellt. Um sich mit diesem Vorgang vertraut zu machen, können Sie Handler für die ItemAppearing- und ItemDisappearing-Ereignisse von ListView installieren. Eine weitere Möglichkeit besteht darin, einen alternativen DataTemplate-Konstruktor zu einzusetzen, der eine Funktion verwendet, die jedes Mal aufgerufen wird, wenn die visuelle Struktur eines Elements erstellt werden muss.

Im Beispiel TextCellListXaml wird ein funktional identisches Programm in XAML gezeigt. Ein DataTemplate-Tag wird auf die ItemTemplate-Eigenschaft von ListView festgelegt, anschließend wird TextCell auf DataTemplate festgelegt. Bindungen mit Eigenschaften der Elemente in der Auflistung werden direkt für die Text- und Detail-Eigenschaften von TextCell festgelegt.

Benutzerdefinierte Zellen

In XAML ist es möglich, ViewCell auf DataTemplate festzulegen und dann eine benutzerdefinierte visuelle Struktur als View-Eigenschaft von ViewCell zu definieren. (Da View die Content-Eigenschaft von ViewCell ist, sind die ViewCell.View-Tags nicht erforderlich.) Diese Vorgehensweise wird im Beispiel CustomNamedColorList gezeigt:

Dreifacher Screenshot der benutzerdefinierten Liste benannter Farben mit

Das Ermitteln der richtigen Größe für alle Plattformen kann schwierig sein. Die RowHeight-Eigenschaft ist nützlich, in einigen Fällen sollten Sie jedoch auf die HasUnevenRows-Eigenschaft zurückgreifen. Diese Eigenschaft ist weniger effizient, erzwingt jedoch das Anpassen der Zeilengröße durch ListView. Bei iOS und Android müssen Sie eine dieser beiden Eigenschaften verwenden, um die richtige Zeilengröße zu erhalten.

Gruppieren der ListView-Elemente

ListView unterstützt das Gruppieren von Elementen sowie das Navigieren zwischen diesen Gruppen. Die ItemsSource-Eigenschaft muss auf eine Auflistung aus Auflistungen festgelegt werden: Das Objekt, auf das ItemsSource festgelegt ist, muss IEnumerableimplementieren. Außerdem muss jedes Element in der Auflistung auch IEnumerableimplementieren. Jede Gruppe sollte zwei Eigenschaften enthalten: eine Textbeschreibung der Gruppe und eine aus drei Buchstaben bestehende Abkürzung.

Die NamedColorGroup -Klasse in der Xamarin.FormsBibliothek Book.Toolkit erstellt sieben Gruppen von NamedColor Objekten. Das Beispiel ColorGroupList zeigt, wie diese Gruppen verwendet werden. Dabei ist die IsGroupingEnabled-Eigenschaft von ListView auf true festgelegt, und die Eigenschaften GroupDisplayBinding und GroupShortNameBinding sind an Eigenschaften in den einzelnen Gruppen gebunden.

Benutzerdefinierte Gruppenheader

Sie können benutzerdefinierte Header für die ListView-Gruppen erstellen, indem Sie die GroupDisplayBinding-Eigenschaft durch GroupHeaderTemplate ersetzen. Auf diese Weise wird eine Vorlage für die Header definiert.

ListView und Interaktivität

Für die Benutzerinteraktion mit ListView wird üblicherweise ein Handler an das ItemSelected- oder ItemTapped-Ereignis angefügt oder eine Datenbindung für die SelectedItem-Eigenschaft festlegt. Es gibt jedoch auch Zellentypen (EntryCell und SwitchCell), die eine Benutzerinteraktion ermöglichen. Darüber hinaus ist es möglich, benutzerdefinierte Zellen zu erstellen, die selbst mit dem Benutzer interagieren. Mit InteractiveListView werden 100 Instanzen von ColorViewModel erstellt. Außerdem kann der Benutzer mithilfe von drei Slider-Elementen die einzelnen Farben ändern. Das Programm verwendet auch die ColorToContrastColorConverter im Xamarin.FormsBook.Toolkit.

ListView und MVVM

ListView spielt in MVVM-Szenarien eine große Rolle. Wenn in einem ViewModel eine IEnumerable-Auflistung vorhanden ist, ist sie oft an ein ListView gebunden. Außerdem implementieren die Elemente in der Auflistung häufig INotifyPropertyChanged, um eine Bindung mit Eigenschaften in einer Vorlage herzustellen.

Eine ViewModels-Auflistung

Um diese Funktion zu veranschaulichen, erstellt die SchoolOfFineArts-Bibliothek mehrere Klassen basierend auf einer XML-Datendatei sowie Bilder von fiktiven Studenten an dieser fiktiven Schule.

Die Student-Klasse wird von ViewModelBase abgeleitet. Die Klasse StudentBody ist eine Auflistung aus Student-Objekten und wird ebenfalls von ViewModelBase abgeleitet. SchoolViewModel lädt die XML-Datei herunter und setzt alle Objekte zusammen.

Das StudentList-Programm verwendet eine ImageCell, um die Studenten und ihre Bilder in einer ListView anzuzeigen:

Dreifacher Screenshot der Studentenliste der Studentenliste

Im Beispiel ListViewHeader wird eine Header-Eigenschaft hinzugefügt, die jedoch nur unter Android angezeigt wird.

Auswahl und der Bindungskontext

Das Programm SelectedStudentDetail bindet den BindingContext eines StackLayout an die SelectedItem-Eigenschaft von ListView. Dadurch kann das Programm detaillierte Informationen zum ausgewählten Studenten anzeigen.

Kontextmenüs

In einer Zelle kann ein Kontextmenü definiert werden, das plattformspezifisch implementiert wird. Um dieses Menü zu erstellen, fügen Sie MenuItem-Objekte zur ContextActions-Eigenschaft der Cell hinzu.

MenuItem definiert fünf Eigenschaften:

Die Eigenschaften Command und CommandParameter implizieren, dass das ViewModel-Objekt für jedes Element Methoden zum Ausführen der gewünschten Menübefehle enthält. In Nicht-MVVM-Szenarien definiert MenuItem zudem ein Clicked-Ereignis.

Dieses Verfahren wird in CellContextMenu veranschaulicht. Die Command-Eigenschaft jedes MenuItem ist an eine Eigenschaft vom Typ ICommand in der Student-Klasse gebunden. Legen Sie die IsDestructive-Eigenschaft für ein MenuItem auf true fest, wenn das Menüelement das ausgewählte Objekt entfernt oder löscht.

Variierende visuelle Elemente

In einigen Fällen sollen die Elemente der ListView basierend auf einer Eigenschaft mit geringfügigen Variationen angezeigt werden. Im Beispiel ColorCodedStudents wird der Name eines Studenten z.B. rot angezeigt, wenn sein Notendurchschnitt unter 2.0 fällt. Dies wird durch die Verwendung eines Bindungswertkonverters ( ThresholdToObjectConverter) in der Xamarin.FormsBibliothek Book.Toolkit erreicht.

Aktualisieren des Inhalts

ListView unterstützt das Herunterziehen der Inhalte, um die Daten zu aktualisieren. Um diese Funktion zu aktivieren, muss das Programm die IsPullToRefresh-Eigenschaft auf true festlegen. ListView reagiert auf das Herunterziehen, indem ihre IsRefreshing-Eigenschaft auf true festgelegt wird. Außerdem wird das Refreshing-Ereignis ausgelöst und (für MVVM-Szenarien) die Execute-Methode ihrer RefreshCommand-Eigenschaft aufgerufen.

Code, der das Refresh-Ereignis oder den RefreshCommand verarbeitet, aktualisiert dann möglicherweise die Daten, die von ListView angezeigt werden, und legt IsRefreshing wieder auf false fest.

Das Beispiel RssFeed veranschaulicht die Verwendung eines RssFeedViewModel, das die Eigenschaften RefreshCommand und IsRefreshing für Datenbindungen implementiert.

TableView und die zugehörigen Intents

Während ListView in der Regel mehrere Instanzen desselben Typs anzeigt, stellt TableView im Allgemeinen eine Benutzeroberfläche für mehrere Eigenschaften unterschiedlicher Typen bereit. Jedes Element ist einer eigenen Cell-Ableitung zum Anzeigen der Eigenschaft oder Bereitstellen einer Benutzeroberfläche zugeordnet.

Eigenschaften und Hierarchien

TableView definiert nur vier Eigenschaften:

Die TableIntent-Enumeration gibt an, wie Sie TableViewverwenden möchten:

Diese Member empfehlen außerdem einige Verwendungsmöglichkeiten für TableView.

Für die Definition einer Tabelle werden eine Reihe weiterer Klassen verwendet:

  • TableSectionBase ist eine abstrakte Klasse, die von BindableObject abgeleitet wird und eine Title-Eigenschaft definiert

  • TableSectionBase<T> ist eine abstrakte Klasse, die von TableSectionBase abgeleitet wird und IList<T> und INotifyCollectionChanged implementiert

  • TableSection wird von TableSectionBase<Cell> abgeleitet

  • TableRoot wird von TableSectionBase<TableSection> abgeleitet

Kurz gesagt verfügt TableView über eine Root-Eigenschaft, die Sie auf ein TableRoot-Objekt festlegen, bei dem es sich um eine Auflistung von TableSection-Objekten handelt. Jedes dieser Objekte ist wiederum ebenfalls eine Auflistung von Cell-Objekten. Eine Tabelle verfügt über mehrere Abschnitte, und jeder Abschnitt enthält mehrere Zellen. Die Tabelle selbst und jeder Abschnitt kann über einen Titel verfügen. Wenngleich TableView mit Cell-Ableitungen arbeitet, wird DataTemplate nicht verwendet.

Ein einfaches Formular

Das EntryForm-Beispiel definiert ein PersonalInformation-Ansichtsmodell. Eine Instanz dieses Modells wird zum BindingContext von TableView. Jede Cell-Ableitung in der zugehörigen TableSection kann anschließend über Bindungen mit Eigenschaften der PersonalInformation-Klasse verfügen.

Benutzerdefinierte Zellen

Im Beispiel ConditionalCells wird EntryForm erweitert. Die ProgrammerInformation-Klasse enthält eine boolesche Eigenschaft, die die Anwendbarkeit von zwei zusätzlichen Eigenschaften regelt. Für diese beiden zusätzlichen Eigenschaften verwendet das Programm eine benutzerdefinierte PickerCell, die auf PickerCell.xaml und PickerCell.xaml.cs in der Bibliothek Xamarin.FormsBook.Toolkit basiert.

Obwohl die IsEnabled-Eigenschaften der beiden PickerCell-Elemente an die boolesche Eigenschaft in ProgrammerInformationgebunden sind, scheint dieses Verfahren nicht zu funktionieren. Aus diesem Grund wird das nächste Beispiel veranschaulicht.

Bedingungsabschnitte

Im Beispiel ConditionalSection werden die beiden bedingten Elemente der Auswahl des booleschen Elements in einer separaten TableSection platziert. Die CodeBehind-Datei entfernt diesen Abschnitt aus der TableView oder fügt ihn basierend auf der booleschen Eigenschaft erneut hinzu.

Ein TableView-Menü

Eine weitere Verwendungsmöglichkeit von TableView ist ein Menü. Im Beispiel MenuCommands wird ein Menü gezeigt, in dem Sie eine kleine BoxView auf dem Bildschirm verschieben können.