Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Treeview Virtualization and erratic scrolling

I have a WPF treeview with a large volume of nested data I have enabled virtualization which is working in terms of the data being loaded. But the scrolling has become unstable until the entire view has been scrolled through once then it settles down some what (still not great). I have override the ScrollViewer and I can see that the extent Height within the VirtualizingStackPanel changes erratically while scrolling.

Does anyone know of way of resolving this?

Any help is apreciated.

Relevant sections of the TreeView Xaml below:

        <TreeView  ItemsSource="{Binding Folders.ObservableTree}" Name="FoldersTreeView"
                AutomationProperties.AutomationId="foldersview_treeview_folders" TabIndex="0" PreviewMouseRightButtonDown="OnPreviewMouseRightButtonDown"
                VirtualizingStackPanel.CleanUpVirtualizedItem="VirtualizingStackPanel_OnCleanUpVirtualizedItem" 
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                ScrollViewer.IsDeferredScrollingEnabled ="True"
                VirtualizingStackPanel.IsVirtualizing="True"
                ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                VirtualizingStackPanel.ScrollUnit="Pixel"
                VirtualizingStackPanel.VirtualizationMode="Standard"
                VirtualizingPanel.IsVirtualizingWhenGrouping="True" 
                VirtualizingStackPanel.CacheLengthUnit="Item">

        <TreeView.ItemsPanel>
                <ItemsPanelTemplate>
                <VirtualizingStackPanel IsItemsHost="True" CanVerticallyScroll="True"/>
            </ItemsPanelTemplate>
            </TreeView.ItemsPanel>
        <TreeView.Template>
            <ControlTemplate>
                <view:ScrollViewer2 Padding="{TemplateBinding Control.Padding}" Focusable="False" Name="TreeViewScrollViewer"  
                              CanContentScroll="True">
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                </view:ScrollViewer2>
            </ControlTemplate>
        </TreeView.Template>
like image 603
Sjblack Avatar asked Feb 09 '17 09:02

Sjblack


1 Answers

Virtualization only works well if all items in the ItemsPresenter (and a TreeView is implemented as a ItemsPresenter with nested ItemsPresenters) have the same height. With a TreeView this is usually not the case.

The main reason for this is that because it is virtualizing, it has to estimate certain things that it would otherwise measure exactly:

The VirtualizationStackPanel will assume all children have the same height as currently visible children and will estimate a desired height based on this (instead of than actually measuring all children), which will be reported to the ScrollViewer, if the children have variable height, this estimate can be way off and will change depending on the scroll position, resulting in a continually resizing scrollbar.

like image 164
Bubblewrap Avatar answered Sep 17 '22 15:09

Bubblewrap