首页 > 其他分享 >WPF 性能优化-列表控件性能

WPF 性能优化-列表控件性能

时间:2024-10-12 10:43:22浏览次数:1  
标签:控件 滚动 虚拟化 性能 子项 列表 VirtualizingStackPanel WPF

下面记录几种针对大数据列表控件性能的增强特性,WPF所有继承自ItemsControl的控件(列表控件)都支持这些增强特性,包括ListBox、ComboBox、ListView、TreeView以及DataGrid。

一、虚拟化
WPF列表控件所提供的最重要的功能就是UI虚拟化。

UI虚拟化是列表只为可见区域中能显示的项创建容器对象的一种技术,对提升列表控件的性能有着显卓的效果。假设有一个数万条记录的ListBox控件,其可见区域只能展示30条记录仪,此时如果使用虚拟化技术,那么ListBox只需要创建30个ListBoxItem(或多几个已保持良好的滑动性能),如果没有使用虚拟化技术,则需要生成属数万个ListBoxItem ,这显然会占用更多的内存,且影响应用的流畅度。

虚拟化的启用

需要注意的是,支持虚拟化的其实是VirtualizingStackPanel容器,此容器控件除了虚拟化支持外,其他的与StackPanel功能是类似的。

ListBox、ListView和DataGrid默认都使用VirtualizingStackPanel来作为子元素的布局容器,因此这些控件默认情况下就是使用虚拟化的,不需要进行额外的处理
ComboBox默认情况下是使用StackPanel来作为子元素的布局容器的,因此要支持虚拟化,必须明确通过提供新的ItemsPanelTemplate将子元素的布局容器设置为VirtualizingStackPanel
TreeView虽然默认都使用VirtualizingStackPanel来作为子元素的布局容器,但是由于早期的WPF中VirtualizingStackPanel不支持层次化数据,为了向后兼容,默认是禁用了虚拟化的,因此要使用虚拟化,需要通过设置 VirtualizingStackPanel.IsVirtualizing="True" 属性开启
ItemsControl默认情况下会使用VirtualizingStackPanel作为子元素的布局容器
破坏虚拟化的因素

很多时候,在不知不觉中虚拟化已经被破坏掉了,下面是几种破坏虚拟化的常见因素:

将列表控件放入不会试图限制其尺寸的容器中时,列表控件会以完整尺寸渲染自身,导致每个子项在内存中都有自己的控件。例如将ListBox控件放入到ScrollViewer或StackPanel中
改变列表控件的模板并且没有使用ItemsPresenter。ItemsPresenter使用ItemsPanelTemplate中设定的子项容器来布局子项,而ItemsPanelTemplate默认的设定是使用VirtualizingStackPanel,如果破坏了这种关系或自己修改了ItemsPanelTemplate的设置,从而使其不使用VirtualizingStackPanel面板,将会丢失虚拟化特性。
不使用数据绑定,例如通过动态创建ListBoxItem来为ListBox控件添加子项,是不会发生虚拟化的。
二、项容器再循环
列表控件在启用虚拟化的情况下,进行滚动时,默认会创建新展示的子项控件,并销毁离开可视区域的子项控件。可以通过设置VirtualizingStackPanel.VirtualizationMode="Recycling"开启像容器再循环模式,这样列表控件会保留少量的子项控件,在滚动时进行服用,只根据新数据更新其中的内容,而不是每次都创建和销毁。这有助于减少内存使用并提高性能,特别是在滚动大量数据时。

VirtualizingStackPanel.VirtualizationMode的有效值为Standard 和 Recycling,默认情况下为Standard

<ListView VirtualizingStackPanel.VirtualizationMode="Recycling">  
   ......
</ListView> 

三、缓存长度
上文中有提及到,VirtualizingStackPanel会多创建几个超过显示范围的子项,以便在开始滚动时候就可以立即显示这些子项,以此来优化交互。我们可以通过使用VirtualizingStackPanel.CacheLength和VirtualizingStackPanel.CacheLengthUnit来进一步调整数量。

VirtualizingStackPanel.CacheLengthUnit:表示缓存的单位,有效值分别为Item、Page、Pixel,其中Page表示可视窗口所能展示的数量的项,Pixel表示像素,适用于项显示不同大小的图片时。
VirtualizingStackPanel.CacheLength:表示缓存指定单位的数量。
值得注意的是,在滚动时,VirtualizingStackPanel会先将可见的项创建并显示后,再在后台中进行缓存的填充,因此缓存对应用程序流畅度的影响很小。

缓存当前显示项的前一页和后一页

<ListBox VirtualizingStackPanel.CacheLength="1" VirtualizingStackPanel.CacheLengthUnit="Page" ....../>

缓存当前显示项的前100项和后100项

<ListBox VirtualizingStackPanel.CacheLength="100" VirtualizingStackPanel.CacheLengthUnit="Item" ....../>

缓存当前显示项的前100项和后500项

<ListBox VirtualizingStackPanel.CacheLength="100,500" VirtualizingStackPanel.CacheLengthUnit="Item" ....../>

四、滚动设置

1、延迟滚动

默认情况下,当用户在滚动条上拖动滑动块时,会实时刷新列表,为了进一步提高滚动性能,可以通过设置ScrollViewer.IsDeferredScrollingEnabled="True"开启延迟滚动,

只有当用户释放滚动滑块时才进行刷新。

<ListBox ScrollViewer.IsDeferredScrollingEnabled="True" ....../>

这个特性需要根据实际情况使用了,虽然可以提高性能,但是无法实时展示滑动到哪个位置了,而实际开发时,用户更喜欢能实时看到当前滑动块的展示位置。

2、滚动单位
VirtualizingStackPanel默认是基于项进行滚动的,也就是说无论是单击滚动条、滚动箭头还是调用ScrollIntoView()方法,在面板上至少会滚动一个完整项,而无法在滚动时展示某个项的一部分。

可以通过VirtualizingStackPanel.ScrollUnit="Pixel"(默认为Item),将VirtualizingStackPanel的滚动设置为基于像素,可以让滚动更加流畅。

<ListBox VirtualizingStackPanel.ScrollUnit="Pixel" ....../>

 



标签:控件,滚动,虚拟化,性能,子项,列表,VirtualizingStackPanel,WPF
From: https://www.cnblogs.com/ywtssydm/p/18460049

相关文章

  • 界面控件DevExpress中文教程 - 如何拓展具有AI功能的文本编辑器(二)
    NLP是人工智能的一个分支,它允许计算机与人类语言进行交互,这包括以有意义/有用的方式理解、解释、生成和回应文本(和语音)的能力。基于NLP的功能允许更好的数据分析、个性化体验、高效的沟通,并导致更明智的决策和提高效率。例如:机器翻译文本摘要文本生成文本分类以及更多…......
  • R语言使用randomForest包中的randomForest函数构建随机森林模型、使用importance函数
    R语言使用randomForest包中的randomForest函数构建随机森林模型、使用importance函数查看特征重要度、使用table函数计算混淆矩阵评估分类模型性能、包外错误估计OOB(out-of-bagerrorestimate)目录R语言使用randomForest包中的randomForest函数构建随机森林模型(Randomfores......
  • DevExpress控件安装、汉化使用教程
    前言DevExpress是一个庞大的控件库,也很是好用(没用过,听说),但是要收费。网上关于DevExpress的教程满天飞,我找了一下午也没找到正确的安装、简单实用教程,还是自己摸索吧。自己动手,丰衣足食。安装DevExpress不像其他控件库一样,直接引用或是附加个dll就可以使用,De......
  • 基于MPPT的太阳能光伏电池simulink性能仿真,对比扰动观察法,增量电导法,恒定电压法
    1.课题概述        在simulink中,实现基于MPPT的太阳能光伏电池,对比对比扰动观察法,增量电导法,恒定电压法三种MPPT方法。 2.系统仿真结果    局部放大可以看到三个算法的对比结果如下:   3.核心程序与模型版本:MATLAB2022a  4.系统原理简......
  • 学习Opencv的第八天——优化Opencv在执行时的性能
    1、使用OpenCV衡量性能cv.getTickCount函数返回从参考事件(如打开机器的那一刻)到调用此函数那一刻之间的时钟周期数。因此,如果在函数执行之前和之后调用它,则会获得用于执行函数的时钟周期数。cv.getTickFrequency函数返回时钟周期的频率或每秒的时钟周期数。因此,要找到执行......
  • WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现C
    1、新建了一个用户控件,里面画了一个实心圆,以及一个文本控件的组合,当作我要实验使用的用户控件(TestUserControl)。 2、在主窗体里面进行引用,可以看到引用以后,会在工具箱上显示新增的用户控件3、为了测试方便,我直接在先前的Lo'gin页面直接进行添加该用户控件,效果如下。 4、......
  • 【Qt】详细Qt基础 (包括自定义控件)
    目录QT概述创建项目项目文件(.pro)main.cppmainwindow.uimainwindow.hmainwindow.cpp窗口类QWidget窗口显示QDialog窗口QPushButton创建显示对象树基本概念功能坐标体系控件ItemWidgetsQListWidgetQTreeWidgetQTableWidget自定义控件QT概述模块功能QtCore......
  • WPF 动画-VisualStateManager
    动画状态-VisualStateManagerVisualStateManager控件可以通过VisualState来定义控件的不同动画状态,然后在C#代码中合适地方,使用VisusalStateManager.GoToState()或VisualStateManager.GoToElementState()方法来切换到对应的状态,从而实现样式的切换。一、用法介绍1、关键成员......
  • 聊聊影响性能测试成熟度的内容项
    目录一、性能测试流程规范1.1、性能需求型模式下的流程规范1.2、性能常态化模式下的流程规范1.3、性能平台化模式下的规范流程二、性能测试环境2.1、无性能测试环境2.2、性能测试与功能测试共用测试环境2.3、有独立的性能测试环境三、工具及平台3.1、性能测试压测工......
  • React如何进行性能优化-方式、原理、示例
    目录一、使用shouldComponentUpdate和React.memo1.使用shouldComponentUpdate(类组件)2.使用React.memo(函数组件)二、使用useMemo三、懒加载四、避免使用匿名函数五、避免使用内联对象六、列表使用key属性一、使用shouldComponentUpdate和React.memo1.使用shouldC......