MAUI Controls: Lists

Lists are a fundamental UI element in modern applications, allowing users to view and interact with collections of data. In .NET MAUI, you can leverage powerful and flexible list controls to display items efficiently, whether it's a simple list of text or complex data-bound items with rich visuals.

This document explores the primary list controls available in .NET MAUI, focusing on CollectionView and ListView, and provides guidance on how to use them effectively.

1. CollectionView

CollectionView is the recommended and most versatile list control in .NET MAUI. It provides a flexible way to display collections of data, supporting various layouts such as linear (vertical or horizontal) and grid arrangements.

1.1. Basic Usage

To use CollectionView, you typically bind it to an observable collection of data. Here's a simple example in XAML:

<CollectionView ItemsSource="{Binding MyItems}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding .}" Padding="10"/>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

In this example, MyItems would be an observable collection (e.g., ObservableCollection<string>) in your ViewModel.

1.2. Data Binding with Complex Objects

When working with more complex data objects, you can bind specific properties within your DataTemplate:

<CollectionView ItemsSource="{Binding Products}">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="local:Product">
            <Grid Padding="10" RowDefinitions="Auto,*">
                <Label Grid.Row="0" Text="{Binding Name}" FontAttributes="Bold"/>
                <Label Grid.Row="1" Text="{Binding Description}"/>
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Here, Product is a C# class with Name and Description properties. The x:DataType attribute improves performance and enables IntelliSense.

1.3. Layout Options

CollectionView supports various layouts:

Example for a horizontal grid:

<CollectionView ItemsSource="{Binding Images}">
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Horizontal" Span="3"/>
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}" HeightRequest="100"/>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

The Span property in GridItemsLayout defines the number of columns (or rows if orientation is vertical).

2. ListView (Legacy)

ListView is an older control that is still supported but CollectionView is generally preferred for new development due to its greater flexibility and performance benefits, especially with large datasets.

2.1. Basic Usage

Similar to CollectionView, ListView binds to data:

<ListView ItemsSource="{Binding MyData}">
    <ListView.ItemTemplate>
        <ViewCell>
            <Label Text="{Binding}" Padding="10"/>
        </ViewCell>
    </ListView.ItemTemplate>
</ListView>

Note the use of ViewCell within the ItemTemplate for ListView.

2.2. Grouping

ListView supports grouping of items, which is a common requirement for lists.

<ListView ItemsSource="{Binding GroupedData}">
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <Label Text="{Binding Key}" FontAttributes="Bold" BackgroundColor="LightGray" Padding="10"/>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>
    <ListView.ItemTemplate>
        <ViewCell>
            <Label Text="{Binding .}" Padding="10"/>
        </ViewCell>
    </ListView.ItemTemplate>
</ListView>

Your data source would need to be structured as a collection of groups, where each group has a Key property and a collection of items.

3. Performance Considerations

When dealing with large lists, performance is crucial. Both CollectionView and ListView implement virtualization, meaning they only create UI elements for the items currently visible on screen. This significantly improves performance.

4. Interactivity

List controls offer various ways to interact with items:

Example of handling selection in CollectionView:

// In your ViewModel or Code-Behind
public ICommand ItemTappedCommand => new Command(async (item) =>
{
    var selectedItem = item as YourDataType;
    if (selectedItem != null)
    {
        // Do something with the selected item
        await DisplayAlert("Item Selected", selectedItem.Name, "OK");
    }
});

And in XAML:

<CollectionView ItemsSource="{Binding MyItems}"
                SelectionChangedCommand="{Binding ItemTappedCommand}"
                SelectionChangedCommandParameter="{Binding SelectedItem}">
    ...
</CollectionView>