There's actually much more to it than just making the ItemsPanelTemplate
use VirtualizingStackPanel
. The default ControlTemplate
for ItemsControl
does not have a ScrollViewer
, which is the key to virtualization. Adding to the the default control template for ItemsControl
(using the control template for ListBox
as a template) gives us the following:
<ItemsControl ItemsSource="{Binding AccountViews.Tables[0]}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Initialized="TextBlock_Initialized"
Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True"
VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ScrollViewer CanContentScroll="True"
Padding="{TemplateBinding Padding}"
Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
(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 times TextBlock_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
with ListBox
:)
Also, check out this Optimizing Performance on MSDN page and notice that ItemsControl
isn't in the "Controls That Implement Performance Features" table, which is why we need to edit the control template.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…