CollectionView vs ListView
CollectionView is the modern MAUI control for displaying scrollable, selectable collections of data, replacing the older ListView. It supports linear, grid, and carousel layouts through the ItemsLayout property (LinearItemsLayout, GridItemsLayout), and it virtualizes items automatically — only realizing the visual elements currently on or near screen — which gives noticeably smoother scrolling on long lists than ListView typically achieved.
Cricket analogy: CollectionView's virtualization is like a stadium only printing tickets for seats currently in view of the broadcast camera, rather than pre-rendering all 90,000 seats at once like an older approach would.
Binding to ObservableCollection<T>
CollectionView.ItemsSource should be bound to an ObservableCollection<T> rather than a plain List<T>. ObservableCollection raises the CollectionChanged event whenever an item is added, removed, or moved, and CollectionView listens for that event to automatically update the visible list — a plain List<T> never raises such notifications, so adding to it silently leaves the UI unchanged until something forces a full rebind.
Cricket analogy: ObservableCollection notifying the UI when a new player is added is like a team app's roster screen updating the instant a selector confirms Shubman Gill's inclusion, without a manual refresh tap.
DataTemplate and Item Selection
The ItemTemplate property takes a DataTemplate defining exactly how each item in the source collection is rendered — the same visual structure is stamped out for every item, with {Binding} inside it resolving against that individual item rather than the page's BindingContext. SelectionMode (None, Single, Multiple) combined with SelectedItem or SelectedItems binding lets the ViewModel react when the user taps a row.
Cricket analogy: DataTemplate is like a fixed scorecard layout applied to every player's row in a lineup — whether it's Kohli or a debutant, the same template renders name, runs, and strike rate consistently.
<CollectionView ItemsSource="{Binding Products}"
SelectionMode="Single"
SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="local:Product">
<Border Margin="6" Padding="10" StrokeShape="RoundRectangle 8">
<VerticalStackLayout>
<Image Source="{Binding ImageUrl}" HeightRequest="100" Aspect="AspectFill" />
<Label Text="{Binding Name}" FontAttributes="Bold" />
<Label Text="{Binding Price, StringFormat='${0:F2}'}" />
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>For lists that mix distinct item shapes — say, a header row and product rows — assign a DataTemplateSelector to ItemTemplate instead of a single DataTemplate. It inspects each item at render time and returns the appropriate template for it.
EmptyView and Layout Options
CollectionView also exposes an EmptyView property for showing a friendly message or graphic when ItemsSource is empty or null, and it supports horizontal scrolling and item spacing via ItemsLayout properties like ItemSpacing, giving you carousel- and grid-style layouts without switching controls or writing custom renderers as older ListView-based approaches sometimes required.
Cricket analogy: EmptyView is like a scoreboard showing 'Rain Delay' instead of a blank screen when there's no play data yet, giving spectators context rather than an empty display.
Binding ItemsSource to a plain List<T> and then calling products.Add(newItem) will not update the UI, because List<T> never raises CollectionChanged. Always back CollectionView.ItemsSource with an ObservableCollection<T> when items are added or removed after the initial bind.
- CollectionView replaces ListView, offering linear, grid, and carousel layouts via ItemsLayout.
- CollectionView virtualizes items, realizing only what's visible for smoother scrolling on long lists.
- ItemsSource should be an ObservableCollection<T> so Add/Remove operations automatically update the UI.
- ItemTemplate defines a DataTemplate stamped out for every item, with bindings resolving against that item.
- SelectionMode and SelectedItem/SelectedItems let the ViewModel react to user taps.
- DataTemplateSelector supports heterogeneous item shapes within a single CollectionView.
- EmptyView displays a friendly placeholder instead of a blank screen when ItemsSource has no items.
Practice what you learned
1. Why should CollectionView.ItemsSource be bound to ObservableCollection<T> instead of List<T>?
2. What property lets CollectionView render items in a grid instead of a vertical list?
3. What does virtualization in CollectionView mean in practice?
4. What is the purpose of EmptyView on a CollectionView?
5. When should you use a DataTemplateSelector instead of a single DataTemplate on ItemTemplate?
Was this page helpful?
You May Also Like
Data Binding Basics
Learn how MAUI connects UI controls to data using the BindingContext and the {Binding} markup extension, including binding modes and INotifyPropertyChanged.
Converters and Commands
Learn how IValueConverter transforms bound data for display and how ICommand/RelayCommand lets buttons and gestures invoke ViewModel logic through bindings.
The MVVM Pattern
Understand how Model-View-ViewModel separates UI from business logic in .NET MAUI, using CommunityToolkit.Mvvm's ObservableObject and RelayCommand to keep code testable.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics