WPF TreeView虚拟化

Car*_*rlo 17 wpf virtualization

我正在试图弄清楚这个虚拟化功能,我不确定我是否理解它错误或发生了什么,但我正在使用ANTS内存分析器来检查虚拟化TreeView中的项目数量,以及它只是不断增加.我有一个包含1,001个项目的TreeView(1个根,1000个子项),我总是得到1,001个TreeViewItems,1,001个ToggleButtons和1,001个TextBlocks.是不是虚拟化应该重复使用这些项目?如果是这样,为什么我每个都有1,001个呢?此外,CleanUpVirtualizedItem永远不会触发.

如果我理解这个错误并且你有资源如何使用它,请告诉我.我通过互联网搜索但没有找到任何有用的东西.

编辑:

甚至树所使用的内存也都来自aporx.当我展开并滚动浏览所有项目时,4mb到12mb.

让我知道谢谢.

这是我的代码.

XAML:

<Window x:Class="RadTreeViewExpandedProblem.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <TreeView x:Name="treeView"
                  VirtualizingStackPanel.IsVirtualizing="True"
                  VirtualizingStackPanel.CleanUpVirtualizedItem="TreeView_CleanUpVirtualizedItem">
            <TreeView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel />
                </ItemsPanelTemplate>
            </TreeView.ItemsPanel>
        </TreeView>
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

C#:

 public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            TreeViewItem rootItem = new TreeViewItem() { Header = "Item Level 0" };

            for (int i = 0; i < 1000; i++)
            {
                TreeViewItem itemLevel1 = new TreeViewItem() { Header = "Item Level 1" };

                itemLevel1.Items.Add(new TreeViewItem());

                rootItem.Items.Add(itemLevel1);
            }

            treeView.Items.Add(rootItem);
        }

        private void TreeView_CleanUpVirtualizedItem(object sender, CleanUpVirtualizedItemEventArgs e)
        {

        }
    }
Run Code Online (Sandbox Code Playgroud)

Aar*_*ver 7

区别在于UI虚拟化(WPF在各种控件上支持开箱即用)与数据虚拟化(WPF不支持开箱即用)。

它归结为UI虚拟化,仅呈现所需内容并在视图内显示。而数据虚拟化仅将给定时间在内存中保存的内容保留下来。

Bea在UI虚拟化和数据虚拟化方面有两篇不错的文章,探讨了差异以及如何解决不支持数据虚拟化的局限性,这似乎正是您所追求的。

编辑:

从3.5 SP1开始,TreeView已添加了对虚拟化的支持。也许删除您的ItemsPanel模板并仅在TreeView上设置属性就足够了。

  • 好的我明白了。虚拟化只能与Binding一起使用……真是太糟糕了。 (2认同)

Car*_*rlo 6

好的,问题是虚拟化仅在TreeView使用Binding时有效,而在像我的示例一样在代码中一个接一个地生成节点时不起作用。真可惜

  • 这应该不是一个太大的障碍,只需使用ObservableCollection绑定树视图并将其添加到集合中即可(如果需要)-无论如何这是更惯用的WPF方式,您不想直接手动添加项目。 (5认同)