I have an ItemsControl
containing a list of data that I would like to virtualize, however VirtualizingStackPanel.IsVirtualizing="True"
does not seem to work with an ItemsControl
.
Is this really the case or is there another way of doing this that I am not aware of?
To test I have been using the following block of code:
<ItemsControl ItemsSource="{Binding Path=AccountViews.Tables[0]}"
VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Initialized="TextBlock_Initialized"
Margin="5,50,5,50" Text="{Binding Path=Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If I change the ItemsControl
to a ListBox
, I can see that the Initialized
event only runs a handful of times (the huge margins are just so I only have to go through a few records), however as an ItemsControl
every item gets initialized.
I have tried setting the ItemsControlPanelTemplate
to a VirtualizingStackPanel
but that doesn't seem to help.
Best Answer
There's actually much more to it than just making the
ItemsPanelTemplate
useVirtualizingStackPanel
. The defaultControlTemplate
forItemsControl
does not have aScrollViewer
, which is the key to virtualization. Adding to the the default control template forItemsControl
(using the control template forListBox
as a template) gives us the following:(BTW, a great tool for looking at default control templates is Show Me The Template)
Things to notice:
You have to set
ScrollViewer.CanContentScroll="True"
, see here for why.Also notice that I put
VirtualizingStackPanel.VirtualizationMode="Recycling"
. This will reduce the numbers of timesTextBlock_Initialized
is called to however many TextBlocks are visible on the screen. You can read more on UI virtualization here .EDIT: Forgot to state the obvious: as an alternate solution, you can just replace
ItemsControl
withListBox
:) Also, check out this Optimizing Performance on MSDN page and notice thatItemsControl
isn't in the "Controls That Implement Performance Features" table, which is why we need to edit the control template.