WPF TreeView虚拟化

时间:2010-12-28 20:21:18

标签: 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>

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)
        {

        }
    }

3 个答案:

答案 0 :(得分:6)

不同之处在于UI虚拟化(WPF在不同控件上支持开箱即用)与数据虚拟化(WPF不支持开箱即用)。

归结为UI虚拟化只能在视图中呈现所需内容;而数据虚拟化只保留在内存中给定时间可能需要的内容。

Bea有两篇关于UI virtualizationdata virtualization的好文章,并介绍了差异以及如何解决不支持数据虚拟化的限制,这似乎是您所追求的。

修改

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

答案 1 :(得分:6)

好的,问题是虚拟化仅在TreeView使用Binding时才有效,而不是像我的例子那样在代码中逐个生成节点。真可惜。

答案 2 :(得分:3)

这不准确。确实,虚拟化仅适用于绑定,但是,正如我在一些示例应用程序中观察到的那样,元素的回收仅发生在树视图的根项上。

因此,如果您只有1个带有1000个孩子的根项目,则不会进行回收,因为只有1个容器可供回收。

如果您有100个根项目,并且每个项目都有100个子项目,那么您将获得部分回收,因为只有根100项目将被回收,但其他9900个子项目将被存储在内存中。

当然,如果树的嵌套级别大于2或3,问题就会变得更糟。

我不知道是否解决了这个问题。