ListBox的滚动方式 分为像素滚动和列表项滚动

通过ListBox的附加属性ScrollViewer.CanContentScroll来设置。因此ListBox的默认模板中,含有ScrollViewer,ScrollViewer下存放列表内容

    <ScrollViewer FocusVisualStyle="{x:Null}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
</ScrollViewer>

而CanContentScroll,true支持逻辑单元(Item),false支持物理单元(像素)。源码如下:

    /// <summary>
/// 获取或设置一个值,该值指示是否支持元素 <see cref="T:System.Windows.Controls.Primitives.IScrollInfo" /> 接口允许滚动。
/// </summary>
/// <returns>
/// <see langword="true" /> 如果 <see cref="T:System.Windows.Controls.ScrollViewer" /> 执行滚动操作使得在逻辑单元; 方面 <see langword="false" /> 如果 <see cref="T:System.Windows.Controls.ScrollViewer" /> 执行滚动操作使得在物理单元方面。
/// 默认值为 <see langword="false" />。
/// </returns>
public bool CanContentScroll
{
get
{
return (bool) this.GetValue(ScrollViewer.CanContentScrollProperty);
}
set
{
this.SetValue(ScrollViewer.CanContentScrollProperty, value);
}
}

滚动

1、像素滚动(物理单元) ScrollViewer.CanContentScroll=false

通过查看源码,我们可以得知CanContentScroll的默认值为false。所以列表ListBox/ListView/DataGrid默认像素滚动

    /// <summary>
/// 标识 <see cref="P:System.Windows.Controls.ScrollViewer.CanContentScroll" /> 依赖属性。
/// </summary>
/// <returns>
/// <see cref="P:System.Windows.Controls.ScrollViewer.CanContentScroll" /> 依赖项属性的标识符。
/// </returns>
[CommonDependencyProperty]
public static readonly DependencyProperty CanContentScrollProperty = DependencyProperty.RegisterAttached(nameof (CanContentScroll), typeof (bool), typeof (ScrollViewer), (PropertyMetadata) new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
  [FriendAccessAllowed]
internal static class BooleanBoxes
{
internal static object TrueBox = (object) true;
internal static object FalseBox = (object) false; internal static object Box(bool value)
{
if (value)
return BooleanBoxes.TrueBox;
return BooleanBoxes.FalseBox;
}
}

像素滚动的优点:平滑--因为按照像素滚动,肉眼分辨较低。

像素滚动的缺点:耗性能-列表中每个项,都要计算出宽高具体数值,且滚动时时计算。如果列表中数量过多,就相当卡了。

2、列表项滚动(逻辑单元) ScrollViewer.CanContentScroll="True"

按照Item高宽为滚动单位。

列表项滚动时,列表只会滚动到一个完整的Item,不会有一个Item只显示一半的情况。

虚拟化 

通过VirtualizingPanel,设置列表ListBox/ListView/DataGrid是否开启虚拟化

VirtualizingPanel其它属性有:

VirtualizingPanel.ScrollUnit="Pixel"--虚拟化滚动单位(像素/单元)

VirtualizingPanel.IsVirtualizing="True" --是否虚拟

VirtualizingPanel.VirtualizationMode="Recycling"

VirtualizingPanel.CacheLengthUnit="Item" --缓存单位

VirtualizingPanel.CacheLength="20,20"-上下缓存数量

开启虚拟化:为何需要设置ScrollViewer.CanContentScroll="True"?

开启虚拟化后,VirtualizingPanel.ScrollUnit会替换原有的ScrollViewer.CanContentScroll滚动方式

虚拟化也有物理单元与逻辑单元之分,滚动单元设置会转移到VirtualizingPanel.ScrollUnit

但是ScrollViewer.CanContentScroll="False"像素滚动,并不仅仅是滚动消耗性能。当数据很多时加载列表,即使开启了虚化化,因计算太耗性能,界面一样卡顿。

有一个解决办法,设置ScrollViewer.CanContentScroll="True"后,在虚拟化设置中,可以设置虚拟化滚动单元VirtualizingPanel.ScrollUnit="Pixel",此即为虚拟化时的像素滚动。

另:虚拟化时的列表项滚动,VirtualizingPanel.ScrollUnit="Item"列表项

注:

VirtualizingPanel.ScrollUnit和ScrollViewer.CanContentScroll的设置滚动单元一样。

设置虚拟单位为逻辑单元时,滚动时会自动滚动到一个完整的项,而不是滚动到项的部分。

因此当列表可见区域,Items数量或者高宽会变化时,列表滚动时会闪现。

列表正确开启虚拟化方式,请看我的另一博客:WPF 列表开启虚拟化的方式

WPF ListBox/ListView/DataGrid 虚拟化时的滚动方式的更多相关文章

  1. WPF 列表虚拟化时的滚动方式

    ListBox的滚动方式 分为像素滚动和列表项滚动 通过ListBox的附加属性ScrollViewer.CanContentScroll来设置.因此ListBox的默认模板中,含有ScrollVie ...

  2. WPF中ItemsControl应用虚拟化时找到子元素的方法

    原文:WPF中ItemsControl应用虚拟化时找到子元素的方法  wpf的虚拟化技术会使UI的控件只初始化看的到的子元素, 而不是所有子元素都被初始化,这样会提高UI性能. 但是我们经常会遇到一个 ...

  3. fullpage.js最后一屏不满一屏时,滚动方式

    这两天公司网页改版用到fullpage.js这个滚屏插件,页面内容整屏的滚动,不成问题,各种设置在网上也都有文档.而我遇到的问题就是,页面内容不满屏的时候,和上面的内容放一块就太挤,单独放一屏就太空, ...

  4. WPF ItemsControl ListBox ListView比较

    在进行列表信息展示时,WPF中提供多种列表可供选择.这篇博客将对WPF ItemsControl, ListBox, ListView进行比较. 相同点: 1. 这三个控件都是列表型控件,可以进行列表 ...

  5. WPF listbox UI虚拟化

    ListBox  默认是UI虚拟化的. 1. 原生使用  <ListBox VirtualizingPanel.IsVirtualizing="True" Virtualiz ...

  6. WPF中ListBox /ListView如何改变选中条背景颜色

    适用ListBox /ListView WPF中LISTVIEW如何改变选中条背景颜色 https://www.cnblogs.com/sjqq/p/7828119.html

  7. WPF拖动DataGrid滚动条时内容混乱的解决方法

    WPF拖动DataGrid滚动条时内容混乱的解决方法 在WPF中,如果DataGrid里使用了模板列,当拖动滚动条时,往往会出现列表内容显示混乱的情况.解决方法就是在Binding的时候给Update ...

  8. 在WPF中弹出右键菜单时判断鼠标是否选中该项

      和上篇在WPF的TreeView中实现右键选定一样,这仍然是一个右键菜单的问题: 这个需求是在一个实现剪贴板的功能的时候遇到的:在弹出右键菜单时,如果菜单弹出位置在ListViewItem中时,我 ...

  9. 自定义WPF ListBox的选择样式

    (下图:进行多项选择的ListBox) 首先介绍一种简单地方法:就是通过自定义SystemColors类的参数来自定义WPF ListBox选择颜色的,SystemColors的HighlightBr ...

随机推荐

  1. hadoop2.6.0实践:A01 问题处理 DEPRECATED: Use of this script to execute hdfs command is deprecated.

    [hadoop@hadoop-master data]$ hadoop dfs -ls /DEPRECATED: Use of this script to execute hdfs command ...

  2. gradle入门(1-2)gradle的依赖管理

    Gradle支持以下仓库格式: Ivy仓库 Maven仓库 Flat directory仓库 一.添加仓库 1.添加Ivy仓库 1.1.通过URL地址添加一个Ivy仓库 我们可以将以下代码片段加入到b ...

  3. 前端开发必备之Chrome开发者工具(一)

    本文介绍的 Chrome 开发者工具基于 Chrome 65版本,如果你的 Chrome 开发者工具没有下文提到的那些内容,请检查下 Chrome 的版本 简介 Chrome 开发者工具是一套内置于 ...

  4. python Mysql 库表

    Mysql 库表    创建 学生信息库表  学生成绩 库表

  5. SpringBoot(六):springboot热部署

    在j2ee项目开发中,热部署插件是JRebel.JRebel的使用为开发人员带来了极大的帮助,且挺高了开发便捷.而在SpringBoot开发生态环境中,SpringBoot热部署常用插件是:sprin ...

  6. C++ STL基本容器使用

    1:关联容器和顺序容器 c++中有两种类型的容器:顺序容器和关联容器,顺序容器主要有:vector.list.deque等.其中vector表示一段连续的内存地址,基于数组的实现,list表示非连续的 ...

  7. JS事件练习题

    1.点击按钮连续弹窗5次 <div class="noe"> <div class="noe1" onClick="n()" ...

  8. Resource 的 IsSealed 问题

    WFP 的 Generic.xaml ,App.xaml 等中的资源会被调用 Freezable. 在后台对该资源进行修改等操作会被提示.资源为密封对象. 如果,确定需要在后台对资源进行修改. 则需要 ...

  9. windows汇编环境配置

    原文地址 软件下载 需要的软件已经打包,包括dosbox和MASM.如果没有这两个软件可以在下面的地址下载. http://hjwblog.com/game/汇编环境.zip 点击下载 安装dosbo ...

  10. ●BZOJ 3561 DZY Loves Math VI

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3561 题解: 莫比乌斯反演 $$\begin{aligned}ANS&=\sum_{ ...