Summary of Chapter 19. Collection views
Notes on this page indicate areas where Xamarin.Forms has diverged from the material presented in the book.
Xamarin.Forms defines three views that maintain collections and display their elements:
Pickeris a relatively short list of string items that allows the user to choose one
ListViewis often a long list of items usually of the same type and formatting, also allowing the user to choose one
TableViewis a collection of cells (usually of various types and appearances) to display data or manage user input
It is common for MVVM applications to use the
ListView to display a selectable collection of objects.
Program options with Picker
Picker is a good choice when you need to allow the user to choose an option from among a relatively short list of
The Picker and event handling
The PickerDemo sample demonstrates how to use XAML to set the
Title property and add
string items to the
Items collection. When the user selects the
Picker, it displays the items in the
Items collection in a platform-dependent manner.
You can also use
SelectedIndex to initialize the selected item, but it must be set after the
Items collection is filled. In XAML, this means that you'll probably use a property element to set
Data binding the Picker
SelectedIndex property is backed by a bindable property but
Items is not, so using data binding with a
Picker is difficult. One solution is to use the
Picker in combination with an
ObjectToIndexConverter such as the one in the Xamarin.FormsBook.Toolkit library. The PickerBinding demonstrates how this works.
Picker now includes
SelectedItem properties that support data binding. See Picker.
Rendering data with ListView
ItemsSource is of type
IEnumerable but it is
null by default and must be explicitly initialized or (more commonly) set to a collection through a data binding. The items in this collection can be of any type.
ListView defines a
SelectedItem property that is either set to one of the items in the
ItemsSource collection or
null if no item is selected.
ListView fires the
ItemSelected event when a new item is selected.
Collections and selections
The ListViewList sample fills a
ListView with 17
Color values in a
List<Color> collection. The items are selectable but by default they are displayed with their unattractive
ToString representations. Several examples in this chapter show how to fix that display and make it as attractive as desired.
The row separator
On iOS and Android displays, a thin line separates the rows. You can control this with the
SeparatorVisibility property is of type
SeparatorVisbility, an enumeration with two members:
Data binding the selected item
SelectedItem property is backed by a bindable property, so it can be either the source or target of a data binding. Its default
OneWayToSource, but generally it is the target of a two-way data binding, particularly in MVVM scenarios. The ListViewArray sample demonstrates this type of binding.
The ObservableCollection difference
The ListViewLogger sample sets the
ItemsSource property of a
ListView to a
List<DateTime> collection and then progressively adds a new
DateTime object to the collection every second using a timer.
ListView doesn't automatically update itself because the
List<T> collection doesn't have a notification mechanism to indicate when items are added to or removed from the collection.
A much better class to use in such scenarios is
ObservableCollection<T> defined in the
System.Collections.ObjectModel namespace. This class implements the
INotifyCollectionChanged interface and consequently fires a
CollectionChanged event when items are added to or removed from the collection, or when they are replaced or moved within the collection. When the
ListView internally detects that a class implementing
INotifyCollectionChanged has been set to its
ItemsSource property, it attaches a handler to the
CollectionChanged event and updates its display when the collection changes.
ObservableLogger sample demonstrates the use of
Templates and cells
By default, a
ListView displays items in its collection using each item's
ToString method. A better approach involves defining a template to display the items.
To experiment with this feature, you can use the
NamedColor class in the Xamarin.FormsBook.Toolkit library. This class defines a static
All property of type
IList<NamedColor> that contains 141
NamedColor objects corresponding to the public fields of the
The NaiveNamedColorList sample sets the
ItemsSource of a
ListView to this
NamedColor.All property, but only the fully-qualified class names of the
NamedColor objects are displayed.
ListView needs a template to display these items. In code, you can set the
ItemTemplate property defined by
ItemsView<TVisual> to a
DataTemplate object using the
DataTemplate constructor that references a derivative of the
Cell has five derivatives:
TextCell— contains two
Labelviews (conceptually speaking)
ImageCell— adds an
EntryCell— contains an
Entryview with a
SwitchCell— contains a
ViewCell— can be any
View(likely with children)
SetBinding on the
DataTemplate object to associate values with the
Cell properties, or to set data bindings on the
Cell properties referencing properties of the items in the
ItemsSource collection. This is demonstrated in the TextCellListCode sample.
As each item is displayed by the
ListView, a small visual tree is constructed from the template, and data bindings are established between the item and the properties of the elements in this visual tree. You can get an idea of this process by installing handlers for the
ItemDisappearing events of the
ListView, or by using an alternative
DataTemplate constructor that uses a function that is called each time an item's visual tree must be created.
The TextCellListXaml shows a functionally identical program entirely in XAML. A
DataTemplate tag is set to the
ItemTemplate property of the
ListView, and then the
TextCell is set to the
DataTemplate. Bindings to properties of the items in the collection are set directly on the
Detail properties of the
In XAML it is possible to set a
ViewCell to the
DataTemplate and then define a custom visual tree as the
View property of
View is the content property of
ViewCell so the
ViewCell.View tags aren't required.) The CustomNamedColorList sample demonstrates this technique:
Getting the sizing right for all the platforms can be tricky. The
RowHeight property is useful but in some cases you'll want to resort to the
HasUnevenRows property, which is less efficient but forces the
ListView to size the rows. For iOS and Android, you must use one of these two properties to get proper row sizing.
Grouping the ListView items
ListView supports the grouping of items and navigating among those groups. The
ItemsSource property must be set to a collection of collections: The object that
ItemsSource is set to must implement
IEnumerable, and each item in the collection must also implement
IEnumerable. Each group should include two properties: a text description of the group and a three-letter abbreviation.
NamedColorGroup class in the Xamarin.FormsBook.Toolkit library creates seven groups of
NamedColor objects. The ColorGroupList sample shows how to use these groups with the
IsGroupingEnabled property of
ListView set to
true, and the
GroupShortNameBinding properties bound to properties in each group.
Custom group headers
It's possible to create custom headers for the
ListView groups by replacing the
GroupDisplayBinding property with the
GroupHeaderTemplate defining a template for the headers.
ListView and interactivity
Generally an application obtains user interaction with a
ListView by attaching a handler to the
ItemTapped event, or by setting a data binding on the
SelectedItem property. But some cell types (
SwitchCell) allow user interaction, and it's also possible to create custom cells that themselves interact with the user. The
InteractiveListView creates 100 instances of
ColorViewModel and allows the user to change each color using a trio of
Slider elements. The program also makes use of the
ColorToContrastColorConverter in the Xamarin.FormsBook.Toolkit.
ListView and MVVM
ListView plays a big role in MVVM scenarios. Whenever an
IEnumerable collection exists in a ViewModel, it is often bound to a
ListView. Also, the items in the collection often implement
INotifyPropertyChanged to bind with properties in a template.
A collection of ViewModels
Student class derives from
StudentBody class is a collection of
Student objects and also derives from
SchoolViewModel downloads the XML file and assembles all the objects.
The StudentList program uses an
ImageCell to display the students and their images in a
Selection and the binding context
The SelectedStudentDetail program binds the
BindingContext of a
StackLayout to the
SelectedItem property of the
ListView. This allows the program to display detailed information about the selected student.
MenuItem defines five properties:
CommandParameter properties imply that the ViewModel for each item contains methods to carry out the desired menu commands. In non-MVVM scenarios,
MenuItem also defines a
The CellContextMenu demonstrates this technique. The
Command property of each
MenuItem is bound to a property of type
ICommand in the
Student class. Set the
IsDestructive property to
true for a
MenuItem that removes or deletes the selected object.
Varying the visuals
Sometimes you'll want slight variations in the visuals of the items in the
ListView based on a property. For example, when a student's grade-point average falls below 2.0, the
ColorCodedStudents sample displays that student's name in red.
This is accomplished through use of a binding value converter,
ThresholdToObjectConverter, in the Xamarin.FormsBook.Toolkit library.
Refreshing the content
ListView supports a pull-down gesture for refreshing its data. The program must set the
IsPullToRefresh property to
true to enable this. The
ListView responds to the pull-down gesture by setting its
IsRefreshing property to
true, and by raising the
Refreshing event and (for MVVM scenarios) calling the
Execute method of its
Code handling the
Refresh event or the
RefreshCommand then possibly updates the data displayed by the
ListView and sets
IsRefreshing back to
The TableView and its intents
ListView generally displays multiple instances of the same type, the
TableView is generally focused on providing a user interface for multiple properties of various types. Each item is associated with its own
Cell derivative for displaying the property or providing a user interface to it.
Properties and hierarchies
TableView defines only four properties:
TableIntent, an enumeration
TableRoot, the content property of
TableIntent enumeration indicates how you intend to use the
These members also suggest some uses for the
Several other classes are involved in defining a table:
TableSectionBase<T>is an abstract class that derives from
TableView has a
Root property that you set to a
TableRoot object, which is a collection of
TableSection objects, each of which is a collection of
Cell objects. A table has multiple sections, and each section has multiple cells. The table itself can have a title, and each section can have a title. Although
TableView makes use of
Cell derivatives, it does not make use of
A prosaic form
The EntryForm sample defines a
PersonalInformation view model, an instance of which becomes the
BindingContext of the
Cell derivative in its
TableSection can then have bindings to properties of the
The ConditionalCells sample expands on EntryForm. The
ProgrammerInformation class includes a Boolean property that governs the applicability of two additional properties. For these two additional properties, the program uses a custom
PickerCell based on a PickerCell.xaml and PickerCell.xaml.cs in the Xamarin.FormsBook.Toolkit library.
IsEnabled properties of the two
PickerCell elements are bound to the Boolean property in
ProgrammerInformation, this technique does not seem to work, which prompts the next sample.
The ConditionalSection sample puts the two items that are conditional on the selection of the Boolean item in a separate
TableSection. The code-behind file removes this section from the
TableView or adds it back based on the Boolean property.
A TableView menu
Another use of a
TableView is a menu. The MenuCommands sample demonstrates a menu that lets you move a little
BoxView around the screen.