2

I'm trying to implement a virtualizing collection for hierarchical controls similar to the one for regular controls presented in this article.

The solution presented in the article relies heavily on the following behavior (from the article):

When an ItemsControl is bound to an IList implementation, rather than an IEnumerable implementation, it will not enumerate the entire list, and instead only accesses the items required for display. It uses the Count property to determine the size of the collection, presumably to set the scroll extents. It will then iterate through the onscreen items using the list indexer. Thus, it is possible to create an IList that can report to have a large number of items, and yet only actually retrieve the items when required.

I found that while ListBox has this behavior, TreeView (which is also an ItemsControl) doesn't behave like this, and all the items are always requested regardless of whether or not they're displayed on the screen.

So, is this a behavior specific just for ListBox and not for every ItemsControl or is it a bug in WPF's TreeView?

I've also been unable to find any mention of this behavior on MSDN, so if anyone finds it documented anywhere I'd love to know about it.

Adi Lester
  • 24,731
  • 12
  • 95
  • 110
  • In the *Remarks* section of [ItemsControl.ItemsPanel](http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemspanel.aspx) it says that the default ItemsPanel for ListBox is [VirtualizingStackPanel](http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.aspx), and [here](http://msdn.microsoft.com/en-us/library/ms747277.aspx#TreeView_Style) MSDN says that the default ItemsPanel for TreeView is an ordinary StackPanel. – Clemens Jul 23 '12 at 07:35
  • @Clemens This happens even when setting `TreeView.ItemsPanel` to `VirtualizingStackPanel` and turning on virtualization with `VirtualizingStackPanel.IsVirtualizing="True"`. – Adi Lester Jul 23 '12 at 07:39
  • Ok, you could have mentioned that in your question. – Clemens Jul 23 '12 at 07:43

1 Answers1

0

There's more to Virtualizing an ItemsControl than just using a VirtualizingStackPanel or setting VirtualizingStackPanel.IsVirtualizing="True"

Here's the important bits of code needed, but see this question for more complete answer

<ItemsControl
    VirtualizingStackPanel.IsVirtualizing="True" <!-- needed -->
    ScrollViewer.CanContentScroll="True" <!-- needed -->
    ... >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel /> <!-- needed -->
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate>
            <ScrollViewer>  <!-- needed -->
                <ItemsPresenter  />
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>
Community
  • 1
  • 1
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Actually, setting `TreeView.ItemsPanel` to `VirtualizingStackPanel` and `VirtualizingStackPanel.IsVirtualizing="True"` is enough to turn on virtualization in a `TreeView` - I used Snoop and saw that `TreeViewItems` were only created for the visible items; but apparently, UI virtualization doesn't necessarily mean that non-visible items won't be accessed. So my question is less about UI virtualization and more about how to make a `TreeView` only access visible elements from its `ItemsSource` (just like `ListBox` does). – Adi Lester Jul 24 '12 at 05:40