简体   繁体   中英

TreeView doesn't perform UI virtualization

I've been checking out the UI virtualization feature for WPF's TreeView control, which as I understand, is available since .NET 3.5 SP1.

I made a simple project to make sure that UI virtualization is performed correctly, and found out that it doesn't work at all - all of the items are retrieved rather than just the ones currently displayed on the screen.

My XAML looks like this

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

And my code behind

    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;
    }

Note that MyList is my own implementation of IList that holds an ArrayList and does nothing more than forward calls to the held ArrayList and write to the console which method/property was called. For example:

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;
    }
}

If I replace my TreeView with a ListBox, UI virtualization works as expected - ie only ~20 items are requested and not the whole 1000.

Am I doing something wrong here?

EDIT

I've also tried replacing the default ItemsPanel to VirtualizingStackPanel , as suggested , but I'm getting the same results.

Default ItemsPanelTemplate for TreeView is StackPanel and not VirtualizingStackPanel that's why you can't see virtualization in it. Whereas for ListBox default ItemsPanelTemplate is VirtualizingStackPanel that's why setting VirtualizingStackPanel.IsVirtualizing="True" works for ListBox.

To enable virtualization on your TreeView apart from setting property VirtualizingStackPanel.IsVirtualizing="True" , you need to override the its default itemsPanelTemplate like this -

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM