【问题标题】:TreeView jumpy scrollingTreeView 跳跃滚动
【发布时间】:2013-01-25 18:10:46
【问题描述】:

我有一个具有以下属性的虚拟化 TreeView:

<TreeView
    ScrollViewer.CanContentScroll="True" 
    VirtualizingPanel.IsVirtualizing="True"
    VirtualizingPanel.IsVirtualizingWhenGrouping="True" 
    VirtualizingStackPanel.ScrollUnit="Pixel"  
    VirtualizingStackPanel.CacheLength="20,20"
    VirtualizingStackPanel.CacheLengthUnit="Item"
    />
  ...
</TreeView>

TreeViewItem 的高度大致相同。

问题是当向下滚动时,滚动条的手柄会改变大小并且滚动“跳跃”,这会导致用户体验很差。

如何获得更流畅的用户体验?

【问题讨论】:

  • 到目前为止,我的结论是 TreeView 几乎不可能实现高性能。所以我将使用列表视图/框来模拟树视图行为。太糟糕了。

标签: wpf scroll treeview virtualization ui-virtualization


【解决方案1】:

我意识到这是一篇旧帖子,您现在可能有一个解决方案,但它有一个简单的答案,因此对于将来可能遇到此问题的任何人,这里是:

您描述的行为是正常的。如果您在 MSDN 中搜索 ScrollViewer.CanContentScroll,这是您使用的第一个属性,您会发现:

ScrollViewer 中的内容可以按物理单位或逻辑单位滚动。物理单位是与设备无关的像素。逻辑单元用于在 ItemsControl 中滚动项目。 ScrollViewer 的默认行为是使用物理单位来滚动其内容。但是,在 CanContentScroll 设置为 true 的情况下,内容可以使用逻辑单元进行滚动。例如,从 ItemsControl 继承的 ListBox、ListView 和其他控件使用逻辑单元进行滚动。如果 CanContentScroll 为 true,则 ExtentHeight、ScrollableHeight、ViewportHeight 和 VerticalOffset 属性的值是项目数,而不是物理单位。

如果您需要物理滚动而不是逻辑滚动,请将宿主 Panel 元素包装在 ScrollViewer 中并将其 CanContentScroll 属性设置为 false。物理滚动是大多数 Panel 元素的默认滚动行为。

因此,这基本上意味着您可以按像素滚动,也可以从集合中滚动整个项目。因此,为了平滑滚动,您需要使用像素进行滚动。为此,您只需将ScrollViewer.CanContentScroll 属性设置为False。事实证明,这毕竟是一个简单的解决方案。

【讨论】:

  • 我似乎记得也这样做了——调整所有这些设置,看看我们是否可以同时获得性能和平滑滚动。不过现在是很久以前的事了,所以我真的不记得了。我们切换到使用 ListView 并模拟树的行为,这当然有些难过。我会跟进这件事,以确保我们没有错过……
【解决方案2】:

不幸的是,设置 ScrollViewer.CanContentScroll = False 将禁用虚拟化,因此对解决这个问题没有真正的帮助。

我发现为 TreeViewItem 的内容设置一个硬编码的高度值会使滚动条表现得更好,但滚动条仍然会调整大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    相关资源
    最近更新 更多