WPF TreeView虚拟化

WPF TreeView虚拟化,wpf,virtualization,Wpf,Virtualization,我试图弄清楚这个虚拟化功能,我不确定我是否理解错了或者发生了什么,但我正在使用ANTS内存分析器来检查虚拟化树状视图中的项目数量,而且它只是不断增加。我有一个包含1001个项目(1个根目录,1000个子项目)的树视图,并且我总是得到1001个树视图项目,1001个切换按钮和1001个文本块。虚拟化不应该重复使用这些项目吗?如果是这样的话,为什么我每个都有1001个?此外,CleanUpVirtualizedItem从不启动 让我知道,如果我理解错了,如果你有资源如何使用这个。我在网上搜索过,但没

我试图弄清楚这个虚拟化功能,我不确定我是否理解错了或者发生了什么,但我正在使用ANTS内存分析器来检查虚拟化树状视图中的项目数量,而且它只是不断增加。我有一个包含1001个项目(1个根目录,1000个子项目)的树视图,并且我总是得到1001个树视图项目,1001个切换按钮和1001个文本块。虚拟化不应该重复使用这些项目吗?如果是这样的话,为什么我每个都有1001个?此外,CleanUpVirtualizedItem从不启动

让我知道,如果我理解错了,如果你有资源如何使用这个。我在网上搜索过,但没有找到任何有用的东西

编辑:

甚至树所使用的内存也是从aporx增长而来的。当我展开并滚动所有项目时,4mb到12mb

让我知道谢谢

这是我的密码

XAML:


C#:

公共部分类窗口1:窗口
{
公共窗口1()
{
初始化组件();
TreeViewItem rootItem=新的TreeViewItem(){Header=“Item Level 0”};
对于(int i=0;i<1000;i++)
{
TreeViewItemLevel1=新的TreeViewItem(){Header=“Item Level 1”};
itemLevel1.Items.Add(新的TreeViewItem());
rootItem.Items.Add(itemLevel1);
}
treeView.Items.Add(rootItem);
}
私有void树视图_CleanUpVirtualizedItem(对象发送方,CleanUpVirtualizedItemEventArgs e)
{
}
}

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

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

Bea有两篇关于和的文章,讨论了不同之处以及如何克服不支持数据虚拟化的限制,这似乎是您所追求的

编辑:


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

好的,问题是虚拟化只在TreeView使用绑定时起作用,而不是像我的示例那样在代码中一个接一个地生成节点时起作用。真糟糕。

这不准确。然而,正如我在一些示例应用程序中所观察到的那样,virtualization只对绑定起作用,这是事实,元素的循环只发生在treeview的根项上

因此,如果您只有一个根项和1000个子项,则不会发生回收,因为只有一个容器可供回收

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

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


我不知道这个问题是否有解决办法。

我理解。在我的问题中,我谈论的是UI虚拟化,这就是为什么我不明白为什么它会为10001项中的每一项创建一个容器,尽管虚拟化设置为true。@Carlos补充了关于删除ItemsPanel模板的说明;因为我认为3.5 SP1的默认模板应该是VirtualzingStackPanel,所以不需要更改模板,只需像通过TreeView那样启用属性。尝试了您在编辑中提到的内容。也不管用。每个控件我都有一千个。这真的很奇怪。而且CleanUpVirtualizedItem事件仍然没有被触发,这是虚拟化不起作用的另一个线索。@Carlos没有隐藏在应用程序某处的样式吗?你已经缩小到上面的代码了吗?另一个尝试是通过数据绑定数据,而不是显式地逐个添加…好吧,我明白了。虚拟化只适用于绑定。。。真糟糕。这不应该是一个太大的障碍,只要使用ObservableCollection将treeview绑定到集合中,并在需要时将您的项目添加到集合中-这是更惯用的WPF方式,无论如何,您不希望直接手动添加项目。我喜欢您的想法。当我在树上上上下滚动时,我就会知道何时需要更多的项目。你认为这种方法行得通吗?
<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>
 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)
        {

        }
    }