Virtualizing Treeview – aka TreeListBox v2.0

 As promised this weekend I re-wrote the TreeListBox (previous article posted here) control to support better virtualization… Basically I changed the whole idea… There are the same properties and same interface so whoever was using the old TreeListBox can just make an update and everything should work properly.

What was wrong in the old implementation was that I was generating the TreeListBoxItems instead of letting the VirtualizingStackPanel to generate them; the VirtualizingStackPanel was only not adding them to the logical tree! I realized this when I was profiling the component for memory.

In the new implementation I changed the whole concept. Basically now I generate a list of TreeListBoxInfo object from the HierarchalItemsSource specified by the user and set it to the ItemsSource of the TreeListBox.

The object transformation is something like the following

List of Persons  – > treelistbox.HierarchalItemsSource -> List of TreeListBoxInfo – > treelistBox.ItemsSource

Basically the TreeListBoxInfo is just an intermediate object that contains information such as the Level, Children and of course it stores the actual data item (in the example above the data item would be the person object)

Ok, so we have a flat list now but if I set the ItemsSource to have a list of TreeListBoxInfo this would mean that all DataTemplates for the TreeListBoxItem would not work because the user doesn’t know that the Items in the ItemsSource are of type TreeListBoxInfo! So here what we do is override the PrepareContainerForItemOverride method. This method allows us to change the object to set for the TreeListBoxItem and so we do the following…

/// <summary>
/// Prepares the new VirtualizingTreeViewItem with the actual business object
/// </summary>
/// <param name=”element”>The element (VirtualizingTreeViewItem) to apply the template</param>
/// <param name=”item”>The business object to set</param>
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
            TreeListBoxItem listItem = element as TreeListBoxItem;
            TreeListBoxInfo actualItem = item as TreeListBoxInfo;
            //prepares the item with the relative VirtualizingTreeViewInfo
            listItem.PrepareItem(actualItem);
            //pass the actual data item instead of the  VirtualizingTreeViewInfo
            base.PrepareContainerForItemOverride(element,   actualItem.DataItem);
}

As you can see we replace the item to prepare with the DataItem of the TreeListBoxInfo.

There is a lot of other things going on in the background such as registering to data binding events for children and finding the correct index where to push a new item in the list but I think that this is all you need to start working!

Please send me an email at marlongrech@gmail.com if you find any bugs or even if you have any suggestions.

Thanks for your support !

DOWNLOAD SOURCE HERE

Regards

[Last Update of Source Code – 06 October 2007 – fixed some memory leaks]