WPF ListBox/ListView/DataGrid 虚拟化时的滚动方式
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 虚拟化时的滚动方式的更多相关文章
- WPF 列表虚拟化时的滚动方式
ListBox的滚动方式 分为像素滚动和列表项滚动 通过ListBox的附加属性ScrollViewer.CanContentScroll来设置.因此ListBox的默认模板中,含有ScrollVie ...
- WPF中ItemsControl应用虚拟化时找到子元素的方法
原文:WPF中ItemsControl应用虚拟化时找到子元素的方法 wpf的虚拟化技术会使UI的控件只初始化看的到的子元素, 而不是所有子元素都被初始化,这样会提高UI性能. 但是我们经常会遇到一个 ...
- fullpage.js最后一屏不满一屏时,滚动方式
这两天公司网页改版用到fullpage.js这个滚屏插件,页面内容整屏的滚动,不成问题,各种设置在网上也都有文档.而我遇到的问题就是,页面内容不满屏的时候,和上面的内容放一块就太挤,单独放一屏就太空, ...
- WPF ItemsControl ListBox ListView比较
在进行列表信息展示时,WPF中提供多种列表可供选择.这篇博客将对WPF ItemsControl, ListBox, ListView进行比较. 相同点: 1. 这三个控件都是列表型控件,可以进行列表 ...
- WPF listbox UI虚拟化
ListBox 默认是UI虚拟化的. 1. 原生使用 <ListBox VirtualizingPanel.IsVirtualizing="True" Virtualiz ...
- WPF中ListBox /ListView如何改变选中条背景颜色
适用ListBox /ListView WPF中LISTVIEW如何改变选中条背景颜色 https://www.cnblogs.com/sjqq/p/7828119.html
- WPF拖动DataGrid滚动条时内容混乱的解决方法
WPF拖动DataGrid滚动条时内容混乱的解决方法 在WPF中,如果DataGrid里使用了模板列,当拖动滚动条时,往往会出现列表内容显示混乱的情况.解决方法就是在Binding的时候给Update ...
- 在WPF中弹出右键菜单时判断鼠标是否选中该项
和上篇在WPF的TreeView中实现右键选定一样,这仍然是一个右键菜单的问题: 这个需求是在一个实现剪贴板的功能的时候遇到的:在弹出右键菜单时,如果菜单弹出位置在ListViewItem中时,我 ...
- 自定义WPF ListBox的选择样式
(下图:进行多项选择的ListBox) 首先介绍一种简单地方法:就是通过自定义SystemColors类的参数来自定义WPF ListBox选择颜色的,SystemColors的HighlightBr ...
随机推荐
- Docker学习笔记 - Docker的基本概念
一.cs架构 Docker客户端:本地或远程 Docker服务端:守护进程Docker Daemon 二.基本概念 Docker镜像:打包阶段,层叠的只读文件系统,引导->root(ubuntu ...
- python网络爬虫与信息提取 学习笔记day3
Day3: 只需两行代码解析html或xml信息 具体代码实现:day3_1 注意BeautifulSoup的B和S需要大写,因为python大小写敏感 import requests r ...
- logback打印日志时添加上下文
尝试上述特性, 配置如下: 效果:
- Hibernate(十五):QBC检索、本地SQL检索和HQL删除
QBC检索 QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口. 1)通过Cr ...
- php过滤表单提交的html等危险代码
表单提交如果安全做得不好就很容易因为这个表单提交导致网站被攻击了,下面我来分享两个常用的php过滤表单提交的危险代码的实例,各位有需要的朋友可参考. PHP过滤提交表单的html代码里可能有被利用引入 ...
- MyBatis 框架系列之基础初始
1.什么是 MyBatis MyBatis 本是 apache 的一个开源项目 iBatis,后改名为 MyBatis,它 是一个优秀的持久层框架,对 jdbc 的操作数据库的过程进行封装,使开发者只 ...
- 3.如何搭建Appium自动化测试环境
整个APP自动化环境安装可以参照虫师博客安装 附以下链接: http://www.cnblogs.com/fnng/category/695788.html 下面介绍运用到工作中遇到的一些问题 1.如 ...
- 以 Angular 的姿势打开 Font-Awesome
环境 Angular: v5.2.9 Font-Awesome: v5.0.10 angular-fontawesome: v0.1.0-9 无须再用传统的 Web Font 方式 以前习惯于 Fon ...
- 实验吧_who are you?(盲注)
who are you? 翻翻源码,抓抓包,乱试一通都没有什么结果 题目中提示有ip,立马应该联想到X-Forwarded-For 虽然知道是这个方面的题,但完全不知道从何入手,悄咪咪去翻一下wp 才 ...
- servlet学习总结
一.web工程结构 1.HTTP协议(hyper text transfer protocol)(超文本传输协议) 机制:请求/响应 机制(request/response)(HttpServletR ...