Treeview虚拟化和不稳定的滚动

Sjb*_*ack 7 wpf treeview scrollbar

我有一个WPF树视图,其中包含大量嵌套数据,我已启用虚拟化,这对于正在加载的数据而言是有效的.但滚动已变得不稳定,直到整个视图滚动一次然后它解决了一些(仍然不是很好).我已经覆盖了ScrollViewer,我可以看到VirtualizingStackPanel中的范围高度在滚动时发生了不正常的变化.

有谁知道解决这个问题的方法?

任何帮助都是相关的.

下面的TreeView Xaml的相关部分:

        <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>
Run Code Online (Sandbox Code Playgroud)

Bub*_*rap 2

仅当 中的所有项目ItemsPresenter(并且 aTreeView实现为ItemsPresenter带有嵌套的a ItemsPresenters)具有相同高度时,虚拟化才能正常工作。对于 aTreeView通常情况并非如此。

这样做的主要原因是,因为它是虚拟化的,所以它必须估计某些本来可以精确测量的东西:

VirtualizationStackPanel假设所有孩子与当前可见的孩子具有相同的高度,并将基于此估计所需的高度(而不是实际测量所有孩子),这将报告给ScrollViewer,如果孩子的身高可变,则该估计可以是并会根据滚动位置而变化,从而导致滚动条不断调整大小。