我一直在检查 WPF 的 TreeView 控件的 UI 虚拟化功能,据我所知,它从 .NET 3.5 SP1 开始可用。

我做了一个简单的项目来确保正确执行 UI 虚拟化,但发现它根本不起作用 - 所有项目都被检索,而不仅仅是当前显示在屏幕上的项目。

我的 XAML 看起来像这样

<TreeView x:Name="myTree" Height="150" ItemsSource="{Binding Items}"
          VirtualizingStackPanel.IsVirtualizing="True"
          VirtualizingStackPanel.VirtualizationMode="Standard"
          ScrollViewer.IsDeferredScrollingEnabled="True" />

而我背后的代码
    public IEnumerable Items { get; set; }

    public MainWindow()
    {
        Items = GenerateList();
        this.DataContext = this;

        InitializeComponent();
    }

    private IEnumerable GenerateList()
    {
        MyList list = new MyList();

        for (int i = 0; i < 1000; i++)
        {
            list.Add("Item " + i);
        }

        return list;
    }

请注意,MyList 是我自己的 IList 实现,它包含一个 ArrayList 并且仅将调用转发到持有的 ArrayList 并将调用的方法/属性写入控制台。例如:
public object this[int index]
{
    get
    {
        Debug.WriteLine(string.Format("get[{0}]", index));
        return _list[index];
    }
    set
    {
        Debug.WriteLine(string.Format("set[{0}]", index));
        _list[index] = value;
    }
}

如果我用 ListBox 替换我的 TreeView,UI 虚拟化会按预期工作 - 即只请求约 20 个项目,而不是整个 1000 个。

我在这里做错了吗?

编辑

我也尝试按照建议将默认的 ItemsPanel 替换为 VirtualizingStackPanel ,但我得到了相同的结果。

最佳答案

TreeView 的默认 ItemsPanelTemplateStackPanel 而不是 VirtualizingStackPanel 这就是为什么你看不到其中的虚拟化。而对于 ListBox,默认 ItemsPanelTemplate 是 VirtualizingStackPanel,这就是为什么设置 VirtualizingStackPanel.IsVirtualizing="True" 适用于 ListBox。

除了设置属性 VirtualizingStackPanel.IsVirtualizing="True" 之外,要在 TreeView 上启用虚拟化,您需要像这样覆盖其默认 itemsPanelTemplate -

<TreeView x:Name="myTree" Height="150" ItemsSource="{Binding Items}"
          VirtualizingStackPanel.IsVirtualizing="True"
          VirtualizingStackPanel.VirtualizationMode="Standard"
          VirtualizingStackPanel.CleanUpVirtualizedItem="myTree_CleanUpVirtualizedItem"
          ScrollViewer.IsDeferredScrollingEnabled="True">
    <TreeView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel IsItemsHost="True" />
        </ItemsPanelTemplate>
    </TreeView.ItemsPanel>
</TreeView>

关于c# - TreeView 不执行 UI 虚拟化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11600323/

10-11 05:25