为什么将ScrollViewer.CanContentScroll设置为false会禁用虚拟化

Par*_* Wu 31 wpf virtualization ui-virtualization scrollviewer

正如大多数WPF开发人员所知,设置ScrollViewer.CanContentScrollfalse禁用虚拟化; 但我想知道它是如何工作的,因为我尝试启用虚拟化,同时设置ScrollViewer.CanContentScrollfalse.

rud*_*ler 48

"ScrollViewer目前允许两种滚动模式:平滑的逐像素滚动(CanContentScroll = false)或逐项逐项滚动(CanContentScroll = true).目前WPF仅在按项目滚动时支持UI虚拟化.基于像素的滚动是也被称为"物理滚动"和基于项目的滚动也称为"逻辑滚动"."

虚拟化需要基于项目的滚动,以便它可以跟踪当前在视图中的逻辑单元(项目)...将ScrollViewer设置为基于像素的滚动,不再有逻辑单元的概念,只有像素!


小智 13

您可以使用(在 .NET >= 4.5 中)恢复虚拟化VirtualizingPanel.ScrollUnit="Pixel"

  • 嗨@Hoddmimes,我解决了它,我在ListView中设置:`ScrollViewer.CanContentScroll =“True”`,`VirtualizingPanel.IsVirtualizing =“True”`,`VirtualizingPanel.ScrollUnit =“Pixel”`和`VirtualizingPanel.IsContainerVirtualizing =“True” "`,并添加:`<ListView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.ScrollUnit="Pixel" VirtualizingPanel.VirtualizationMode="Recycling"/> </ItemsPanelTemplate> </ListView.ItemsPanel> ` 并且它有效。 (3认同)
  • 这确实有效!这是我的[示例](https://gist.github.com/PiN73/1559e6c940dae092a722e71746b87160) 和 `<ItemsControl>` (3认同)

小智 7

UI虚拟化

我经常被问到是否有办法解决这个限制.嗯,一切皆有可能,但没有简单的解决方法.您必须重新实现当前虚拟化逻辑的重要部分,以将基于像素的滚动与UI虚拟化相结合.您还必须解决随之而来的一些有趣问题.例如,当项目容器具有不同高度时,如何计算拇指的大小?(请记住,您不知道虚拟化容器的高度 - 您只知道当前显示的容器的高度.)您可以根据您知道的高度假设平均值,或者您可以保留列表中的项目高度作为项目被带入内存(当用户与控件交互时,这将增加拇指大小的准确性).您还可以确定基于像素的滚动仅适用于具有相同高度的项目 - 这将简化解决方案.所以,是的,你可以想出一个解决方案来解决这个限制,但这不是微不足道的.