【问题标题】:why setting ScrollViewer.CanContentScroll to false disable virtualization为什么将 ScrollViewer.CanContentScroll 设置为 false 禁用虚拟化
【发布时间】:2011-04-13 01:57:12
【问题描述】:

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

【问题讨论】:

  • 并不是所有的控件都是这样的。例如TreeView.

标签: wpf virtualization scrollviewer ui-virtualization


【解决方案1】:

"ScrollViewer 目前允许两种滚动模式:平滑逐像素滚动(CanContentScroll = false)或离散逐项滚动(CanContentScroll = true)。目前WPF仅在逐项滚动时支持UI虚拟化。像素-基于滚动也称为“物理滚动”,基于项目滚动也称为“逻辑滚动”。”

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

【讨论】:

  • 苹果的iOSUITableView可以完美处理这个问题,无论是内容滚动还是虚拟化,只能说明微软不擅长UI优化。
【解决方案2】:

UI Virtualization

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 嗨@Hoddmimes 我试过了,但它不起作用,还有什么需要打开它才能在基于像素的单元上工作吗?我尝试设置VirtualizingPanel.ScrollUnit="Pixel"VirtualizingPanel.CacheLengthUnit="Pixel",以及CacheLength 等其他属性,但没有任何效果
    • 嗨@Hoddmimes,我解决了,我在ListView中设置:ScrollViewer.CanContentScroll="True",`VirtualizingPanel.IsVirtualizing="True", VirtualizingPanel.ScrollUnit="Pixel"`和VirtualizingPanel.IsContainerVirtualizable="True",和添加:<ListView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.ScrollUnit="Pixel" VirtualizingPanel.VirtualizationMode="Recycling"/> </ItemsPanelTemplate> </ListView.ItemsPanel> 就可以了。
    • 这确实有效!这是我的example<ItemsControl>
    猜你喜欢
    • 1970-01-01
    • 2014-06-20
    • 2011-08-04
    • 2017-09-10
    • 2015-09-16
    • 2015-09-16
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    相关资源
    最近更新 更多