You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF:如何排序ListBox的ItemSource而不触发所有控件构造函数?

WPF ListBox 集合变动时重复创建控件的性能优化方案

问题场景

我使用的ListBox控件,其ItemsSource绑定到ObservableCollection<ContainerViewModel>类型的Containers属性,每个列表项通过ContainerUserControl展示。但执行以下操作时,所有ContainerUserControl的构造函数都会被触发,数据量大时会造成严重性能问题:

  • 重新赋值排序后的集合
  • 调用Move方法对集合进行原地排序
  • 切换ItemsSource

原因排查

经检查发现,ListBox模板中的ScrollViewer设置了CanContentScroll="False",这个配置会禁用UI虚拟化,导致集合每次变动时都需要重建所有列表项控件,无法复用已创建的控件实例。

解决方案

通过以下两步调整,既能启用UI虚拟化,又能保留原有滚动行为:

  1. 将ListBox模板内ScrollViewer的CanContentScroll属性设置为True——这是开启UI虚拟化的必要条件
  2. 给ListBox添加附加属性VirtualizingPanel.ScrollUnit="Pixel",确保滚动保持原有的像素级平滑体验

修改后的ListBox示例代码:

<ListBox ItemsSource="{Binding Containers}"
         VirtualizingPanel.ScrollUnit="Pixel">
    <ListBox.Template>
        <ControlTemplate TargetType="ListBox">
            <ScrollViewer CanContentScroll="True"
                          Padding="{TemplateBinding Padding}">
                <ItemsPresenter />
            </ScrollViewer>
        </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:ContainerUserControl />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

内容的提问来源于stack exchange,提问作者Bardak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:32:10