WPF TreeView Virtualization

Carlo picture Carlo · Dec 28, 2010 · Viewed 15.7k times · Source

I'm trying to figure out this virtualization feature, I'm not sure if I'm understanding it wrong or what's going on, but I'm using the ANTS memory profiler to check the number of items in a virtualized TreeView, and it just keeps increasing. I have a TreeView with 1,001 items (1 root, 1000 sub-items), and I always get up to 1,001 TreeViewItems, 1,001 ToggleButtons and 1,001 TextBlocks. Isn't virtualization supposed to re-use the items? If so, why would I have 1,001 of each? Also, the CleanUpVirtualizedItem never fires.

Let me know if I'm understanding this wrong and if you have resources on how to use this. I've searched over the internet but haven't found anything useful.

EDIT:

Even the memory used by the tree grows from aporx. 4mb to 12mb when I expand and scroll through all the items.

Let me know thanks.

This is my code.

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

        }
    }

Answer

Aaron McIver picture Aaron McIver · Dec 28, 2010

The difference is UI virtualization (which WPF supports out of the box on varying controls) versus data virtualization (which WPF does not support out of the box).

It boils down to UI virtualization only rendering what is needed and within view; while data virtulization only holding what may be needed at a given time in memory.

Bea has two great posts about UI virtualization and data virtualization and goes into the differences and how to workaround the limitation of no support for data virtualization which appears to be what you are after.

EDIT:

As of 3.5 SP1 support for virtualization was added to the TreeView. Perhaps removing your ItemsPanel template and just setting the properties on the TreeView should suffice.