Share via


How to: Improve the Performance of a TreeView

If a TreeView contains many items, the amount of time it takes to load may cause a significant delay in the user interface. You can improve the load time by setting the VirtualizingStackPanel.IsVirtualizing attached property to true. The UI might also be slow to react when a user scrolls the TreeView by using the mouse wheel or dragging the thumb of a scrollbar. You can improve the performance of the TreeView when the user scrolls by setting the VirtualizingStackPanel.VirtualizationMode attached property to Recycling.

Example

Description

The following example creates a TreeView that sets VirtualizingStackPanel.IsVirtualizing to true and VirtualizingStackPanelVirtualizationMode to Recycling to optimize its performance.

Code

<StackPanel>
  <StackPanel.Resources>
    <src:TreeViewData x:Key="dataItems"/>


    <HierarchicalDataTemplate DataType="{x:Type src:ItemsForTreeView}"
                              ItemsSource="{Binding Path=SecondLevelItems}">

      <!--Display the TopLevelName property in the first level.-->
      <TextBlock Text="{Binding Path=TopLevelName}"/>

      <!--Display each string in the SecondLevelItems property in
          the second level.-->
      <HierarchicalDataTemplate.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding}"/>
        </DataTemplate>
      </HierarchicalDataTemplate.ItemTemplate>

      <!--Set the foreground of the items in the second level
          to Navy.-->
      <HierarchicalDataTemplate.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
          <Setter Property="Foreground" Value="Navy"/>
        </Style>
      </HierarchicalDataTemplate.ItemContainerStyle>
    </HierarchicalDataTemplate>
  </StackPanel.Resources>

  <!--Set VirtualizingStackPanel.IsVirtualizing to true and
      VirtualizingStackPanel.VirtualizationMode to Recycling
      to improve scrolling performance in the TreeView.-->
  <TreeView Height="200" ItemsSource="{Binding Source={StaticResource dataItems}}"
            VirtualizingStackPanel.IsVirtualizing="True"
            VirtualizingStackPanel.VirtualizationMode="Recycling">

    <!--Expand each TreeViewItem in the first level and 
        set its foreground to Green.-->
    <TreeView.ItemContainerStyle>
      <Style TargetType="TreeViewItem">
        <Setter Property="IsExpanded" Value="True"/>
        <Setter Property="Foreground" Value="Green"/>
      </Style>
    </TreeView.ItemContainerStyle>
  </TreeView>
</StackPanel>

The following example shows the data that the previous example uses.

Public Class TreeViewData
    Inherits ObservableCollection(Of ItemsForTreeView)

    Public Sub New()
        For i As Integer = 0 To 99
            Dim item As New ItemsForTreeView()
            item.TopLevelName = "item " & i.ToString()
            Add(item)
        Next 
    End Sub 
End Class 


Public Class ItemsForTreeView
    Private _TopLevelName As String 
    Public Property TopLevelName() As String 
        Get 
            Return _TopLevelName
        End Get 
        Set(ByVal value As String)
            _TopLevelName = value
        End Set 
    End Property 
    Private level2Items As ObservableCollection(Of String)

    Public ReadOnly Property SecondLevelItems() As ObservableCollection(Of String)
        Get 
            If level2Items Is Nothing Then
                level2Items = New ObservableCollection(Of String)()
            End If 
            Return level2Items
        End Get 
    End Property 

    Public Sub New()
        For i As Integer = 0 To 9
            SecondLevelItems.Add("Second Level " & i.ToString())
        Next 
    End Sub 
End Class
public class TreeViewData : ObservableCollection<ItemsForTreeView>
{

    public TreeViewData()
    {
        for (int i = 0; i < 100; ++i)
        {
            ItemsForTreeView item = new ItemsForTreeView();
            item.TopLevelName = "item " + i.ToString();
            Add(item);
        }
    }
}


public class ItemsForTreeView
{
    public string TopLevelName { get; set; }
    private ObservableCollection<string> level2Items;

    public ObservableCollection<string> SecondLevelItems
    {
        get 
        {
            if (level2Items == null)
            {
                level2Items = new ObservableCollection<string>();
            }
            return level2Items;
        }
    }

    public ItemsForTreeView()
    {
        for (int i = 0; i < 10; ++i)
        {
            SecondLevelItems.Add("Second Level " + i.ToString());
        }
    }
}

See Also

Concepts

Optimizing Performance: Controls

Change History

Date

History

Reason

February 2009

Added Visual Basic example.

Customer feedback.

July 2008

Added topic to show the new UI virtualization and container recycling features.

SP1 feature change.