When I have the following TreeView in XAML (ItemsSource is set via code-behind to a long list of lists of lists):
<TreeView x:Name="Tree"
VirtualizingPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<!-- ItemTemplate and ItemContainerStyle ommitted for brevity -->
</TreeView>
virtualization works just fine. However, when I tried overriding the TreeView's template, along with the inner ScrollViewer's template, virtualization disappeared. My template seems identical to the default, with the exception of a colored rectangle that I took out which was the entire motivation for redefining the template.
<TreeView.Template>
<ControlTemplate TargetType="{x:Type TreeView}">
<ScrollViewer Focusable="False"
CanContentScroll="True">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<ScrollContentPresenter Grid.Column="0" Grid.Row="0" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Orientation="Vertical"
Grid.Row="0" Grid.Column="1"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar x:Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1" Grid.Column="0"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ScrollViewer.Content>
<ItemsPresenter x:Name="ItemsPresenter" />
</ScrollViewer.Content>
</ScrollViewer>
</ControlTemplate>
I've temporarily gotten around this by just making a transparent SolidColorBrush
named {x:Static SystemColors.ControlBrushKey}
in the TreeView's resources, but I'd prefer to know what I've done incorrectly.
I found the problem. In the
ScrollViewer
template, theScrollContentPresenter
needs to haveCanContentScroll
set to its templated parent's value.