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

如何为嵌套ListView的ItemsControl启用UI虚拟化?设置相关属性后未生效

WPF嵌套列表虚拟化失效的解决方案

咱们来拆解一下你遇到的问题——外层的全局ScrollViewer是导致虚拟化彻底失效的核心原因。当你把ItemsControl塞进ScrollViewer里时,ItemsControl会获得无限的垂直空间(因为ScrollViewer允许内容无限延伸),这就导致里面的每个ListView也会拿到足够的高度去渲染所有2000条Appointment,完全不需要自身滚动,虚拟化自然就“躺平”了。

下面给你一套可行的修复方案,附带修改后的完整代码:

核心修复思路

  • 移除外层的全局ScrollViewer,让ItemsControl和ListView各自管理自己的滚动区域
  • 给每个ListView设置明确的高度约束(或通过布局自动限制),触发它内部的ScrollViewer生效
  • 正确配置ItemsControl的虚拟化规则(未来如果DaySchedule数量增多,这个设置也能帮上忙)

修改后的完整XAML代码

<Window x:Class="WpfApp8.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:local="clr-namespace:WpfApp8" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        Title="MainWindow" Width="800" Height="450" 
        mc:Ignorable="d">
    <!-- 移除外层全局ScrollViewer,让ItemsControl自行处理滚动 -->
    <ItemsControl ItemsSource="{Binding}"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.VirtualizationMode="Recycling">
        <!-- 配置ItemsControl使用VirtualizingStackPanel,开启自身虚拟化 -->
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <!-- 重写模板,内置带CanContentScroll="True"的ScrollViewer(虚拟化关键配置) -->
        <ItemsControl.Template>
            <ControlTemplate TargetType="ItemsControl">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ScrollViewer Padding="{TemplateBinding Padding}"
                                  CanContentScroll="True"
                                  Focusable="False">
                        <ItemsPresenter />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="0 0 0 15">
                    <TextBlock FontSize="20" Text="Schedule For" />
                    <TextBlock FontSize="20" Text="{Binding DayRoundedDateTime}" />
                    <!-- 给ListView设置固定高度(或用MaxHeight),触发内部ScrollViewer激活 -->
                    <ListView Margin="10" 
                              Height="320"
                              ItemsSource="{Binding Appointments}"
                              VirtualizingPanel.IsVirtualizing="True"
                              VirtualizingPanel.VirtualizationMode="Recycling">
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                                <GridViewColumn Header="StartTime" DisplayMemberBinding="{Binding StartTime}" />
                                <GridViewColumn Header="EndTime" DisplayMemberBinding="{Binding EndTime}" />
                            </GridView>
                        </ListView.View>
                    </ListView>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

关键修改点说明

  1. 移除外层ScrollViewer:这是最核心的一步,它直接解决了“无限高度”导致虚拟化失效的问题。
  2. 给ListView设置高度约束:我这里用了Height="320",你也可以换成MaxHeight,或者通过Grid的行布局自动分配空间——只要ListView的内容超过这个高度,它内部的ScrollViewer就会启动,进而触发虚拟化。
  3. ItemsControl的虚拟化配置:通过VirtualizingStackPanel和带CanContentScroll="True"的ScrollViewer,确保当DaySchedule数量增多时,ItemsControl自身也能实现虚拟化。
  4. 简化GridView绑定:把原来的CellTemplate换成DisplayMemberBinding,减少不必要的模板嵌套,进一步提升性能(可选但推荐)。

修改完成后,你再用Snoop检查会发现:ListView只会渲染当前可见区域的项(大概十几到几十条),而不是全部2000条,虚拟化成功生效。

额外注意事项

WPF的虚拟化有个硬性要求:控件必须有明确的高度限制,并且自身的ScrollViewer要开启CanContentScroll="True"(它告诉ScrollViewer按“项”滚动,而不是按像素滚动,这是虚拟化的必要条件)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:08:15