我有774个项目的List
。当我将它设置为绑定到ItemsSource
的ViewModel的Items
属性(也是List
)时,大约需要10秒以上。
我已经尝试了Virtualizing an ItemsControl?的答案,它没有工作-仍然10秒以上。
这是未经修改的代码。请注意,**ItemsControl
位于ScrollViewer
**内部。
XAML:
<Grid d:DataContext="{x:Static local:RulesListDesignModel.Instance}" Background="{StaticResource ForegroundLightBrush}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:RulesListItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
C#
ViewModelApplication.CurrentRulesListViewModel.Items = mList;
这是根据Virtualizing an ItemsControl?的答案修改代码后的XAML(似乎需要10秒多一点):
<Grid d:DataContext="{x:Static local:RulesListDesignModel.Instance}" Background="{StaticResource ForegroundLightBrush}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Items}"
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:RulesListItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer
Padding="{TemplateBinding Control.Padding}"
Focusable="False">
<ItemsPresenter
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</ScrollViewer>
</Grid>
1条答案
按热度按时间ghg1uchk1#
您应该使用
ListBox
或ListView
,它们集成了ScrollViewer
,并且默认启用了UI虚拟化。没有必要使用更基本的ItemsControl
。您应该尝试以下方法来使用UI虚拟化:
将
VirtualizingStackPanel.VirtualizationMode
设置为VirtualizationMode.Recycling
可提高滚动性能。如果你想继续使用
ItemsControl
(为什么?)您需要重新编写可视化树。您目前正在使用两个
ScrollViewers
。一个在模板内部,另一个包裹在ItemsControl
周围。请注意,由于ScrollViewer.CanContentScroll
默认为false
,因此内部ScrollViewer
负责禁用UI虚拟化。将CanContentScroll
设置为true
是必要的,因为它将滚动单位设置为item(而不是pixel)。VirtualizingStackPanel
需要知道可见项的数量。您应该删除外部的
ScrollViewer
,您的性能应该会显着提高:但更重要的是专注于您的自定义
RulesListItemControl
。为每个项目加载此控件。复杂的控件会引入复杂的初始化。应尝试缩减此控件的视觉树。删除所有不需要的
Border
,用TextBlock
替换Label
,重新访问触发器等。目标是减少每个项目容器的呈现时间。要做到这一点,您需要覆盖用于组成
RulesListItemControl
的控件的ControlTemplate
。