Using virtualization with a list or grid (XAML)
[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]
Many apps display and manipulate collections of data, like a list of search results or an album of photos. When the collection is very large, performance can be degraded when displaying or manipulating the collection. To improve performance with large data sets, you can use virtualization. ItemsControls support both UI and data virtualization.
Note ItemsControl is the base class for several common collection controls, including ListView, GridView, FlipView, ListBox, and ComboBox controls. These examples use the ListView and GridView controls, but the info applies to generally to ItemsControls.
UI virtualization
When you add an item to an ItemsControl, the item is wrapped in an item container. For example, an item added to a ListView is wrapped in a ListViewItem. Without UI virtualization, the entire data set is kept in memory and an item container is also created for each item in the data set. A ListView that's bound to a collection of 1000 items will also create 1000 ListViewItem containers that are stored in memory.
With UI virtualization, the data set is still kept in memory, but an item container is created only when the item is nearly ready to be shown in the UI. A ListView using UI virtualization might keep only 20 ListViewItem objects in memory. It creates or re-uses the ListViewItems as needed when the user scrolls through the list. (The number of ListViewItem objects depends on how many items are displayed in the UI.) By default, ItemsControl, and the standard controls derived from it, support UI virtualization. But UI virtualization is disabled under some circumstances. We look at these circumstances now so you can make informed decisions in your app design.
Viewport size
When discussing virtualization, it's important to understand the concept of the viewport, or the area of the ItemsControl that displays content. You also need to understand how a parent container affects the size of a control's viewport.
Some containers restrict the size of their children. Here, we place a GridView inside a Grid. The viewport of the GridView is restricted to the size of the parent Grid. The user can scroll hidden items into view by using scroll bars.
<Grid Height="400" Width="600">
<GridView Background="DarkGreen" ItemsSource="{Binding}"/>
</Grid>
Other containers let their children use unlimited space to display their content, even if the space extends beyond the visible bounds of the container. Here, we place the same GridView inside a Canvas. The visible bounds of the Canvas are outlined in blue. The viewport of the GridView grows to fit all its items, and stretches beyond the visible bounds of the container. (The grayed out items in this image are not visible in an actual app.) There are no scroll bars, so the user can't scroll hidden items into view.
<Canvas Height="400" Width="600">
<GridView Background="DarkGreen" ItemsSource="{Binding}"/>
</Canvas>
When the size of the ItemsControl's viewport isn't restricted, the control doesn't perform virtualization. Instead, it creates an item container for each item in its collection. Some common containers that don't restrict the viewport size are Canvas, StackPanel, and ScrollViewer. You can enable virtualization in this situation by setting the size of ItemsControl directly, instead of letting it be sized by its parent container.
Here, we set the Height and Width on the GridView. This restricts the size of the viewport, and items outside of the viewport are virtualized.
<Canvas>
<GridView Background="DarkGreen" ItemsSource="{Binding}"
Height="400" Width="600"/>
</Canvas>
ItemsPanel
An ItemsControl uses its ItemsPanel to determine how items are arranged in the UI. Your app design might require that you change the default ItemsPanel for a different one. If the new panel supports UI virtualization, the control continues to perform virtualization as before. Standard virtualizing panels include WrapGrid and VirtualizingStackPanel.
If you replace the default panel in an ItemsControl with a non-virtualizing panel, like VariableSizedWrapGrid or StackPanel, UI virtualization is disabled for that control.
Grouped data
UI virtualization is not supported for grouped data. For more info about grouping data, see How to group items in a list or grid. If you need to provide quick navigation through a large set of grouped data, consider using a SemanticZoom control. For more info, see Quickstart: Adding SemanticZoom controls.
Data virtualization
With UI virtualization, the complete data set is stored in memory. Sometimes, your data set is so large that it can't or shouldn't be stored in memory all at once. In this case, you can use data virtualization to get only a subset of the data to work with. The ItemsControl can still apply UI virtualization to the subset of data created by data virtualization.
Random access virtualization
Random access data virtualization lets you retrieve a subset of data from anywhere in the complete data set. For example, if a ListView is bound to a collection of 100,000 items and the user scrolls to the middle of the collection, your app might download only items 50,000 – 50,050. If they then scroll to the end of the list, the app downloads items 99,950 – 100,000. The scroll bar's scroll indicator, or thumb, is always sized to represent its position in the complete 100,000 item data set.
To use random access data virtualization, you must use a data source that implements INotifyCollectionChanged and IObservableVector.
Incremental virtualization
With incremental data virtualization, your app downloads data sequentially. For example, if a ListView is bound to a collection of 100,000 items, your app might download only items 1-50. The scroll bar's thumb is sized to represent its position in the initial 50 item data set. When the user scrolls near the end of the list, items 51 – 100 are downloaded. The scroll bar's thumb is resized to represent its position in the updated 100 item data set.
To use incremental data virtualization, you must use a data source that implements ISupportIncrementalLoading. When you use incremental data virtualization with a ListView or GridView, you can use these members to control data loading: DataFetchSize, IncrementalLoadingThreshold, IncrementalLoadingTrigger, LoadMoreItemsAsync.
Related topics
Quickstart: Adding ListView and GridView controls