WPF的UI虚拟化

简介: 原文:WPF的UI虚拟化许多时候,我们的界面上会呈现大量的数据,如包含数千条记录的表格或包含数百张照片的相册。由于呈现UI是一件开销比较大的动作,一次性呈现数百张照片就目前的电脑性能来说是需要占用大量内存和时间的。
原文: WPF的UI虚拟化

许多时候,我们的界面上会呈现大量的数据,如包含数千条记录的表格或包含数百张照片的相册。由于呈现UI是一件开销比较大的动作,一次性呈现数百张照片就目前的电脑性能来说是需要占用大量内存和时间的。因此需要对其进行优化。以前采用的方案大多数是翻页,翻页在某种程度上造成用户浏览的中断,因此现在往往采用一种新的方案——UI虚拟化。

UI虚拟化的原理是:但是由于显示器和人眼的限制,用户往往只会同时看到其中的数十条数据,因此只要在界面上渲染用户所看到的那些数据即可,对于用户呈现的界面仍然是一样的。微软的MSDN文档UI虚拟化说明的比较详细,这里就不累述了。

关于UI虚拟化的实现,其核心则是VirtualPanel,在WPF中内置的VirtualPanel貌似只有VirtualizingStackPanel一个,不过这个也是最实用的,一般常用于表格之类的数据呈现。如果需要其它布局方式的Panel,则需要自己实现,MSDN Blog上有一系列文章介绍得比较详细:

文章最后也附带了一个VirtualizingTilePanel,实现了一个类似WrapPanel的效果(它要求里面的元素大小是相等的)。用于照片浏览之类的持续还是比较方便的,不知道为什么M$官方没有带这个。原文的.Net版本比较老,是直接编译不过去的,需要自行修改一下。

 

实现自定义VirtualizingPanel并非很复杂,首先介绍介绍几个前置条件:

1. VirtualizingPanel是用于UI虚拟化的,它是用来做ItemsControl的ItemTemplate的,而不是像普通Panel那样直接控制Children。因此,它必须同ItemsControl及其子类(如DataGrid、ListBox)搭配使用,并继承自VirtualizingPanel。

2. VirtualizingPanel是需要和ScrollViewer一起使用的,没有ScrolViewer的话,所有控件都是可见的,谈不上虚拟化。需要注意的是,ItemsControl的默认Template没有ScrollViewer,在ItemsControl中使用VirtualizingPanel时,需要修改一下Template,加上ScrollViewer,并设置CanContentScroll="True"。

3. UI虚拟化是需要在不呈现所有的UI控件前提下知道当前视图下元素呈现效果的,如果所有的数据都转换了为控件的话,也就谈不上虚拟化了。也就是说,不能靠Measure和Arrange所有子元素来确定布局。

 

具体实现的时候一般有如下几个功能点:

  1. Panel需要实现IScrollInfo接口,这样才能手动控制滚动时候的界面虚拟化。关于IScrollInfo接口,我前面的文章中有一些介绍,可以参考一下。
  2. Panel需要能只根据数据感知整体的布局。常见的有三种方案:1. 在Panel中直接指定每个子元素所占据的空间大小,2. 拿第一个子元素所占据的大小来衡量其它子元素所占据的大小,3.数据中直接声明它所需要的大小
  3. Panel根据当前窗口的大小呈现元素(加载可见元素,删除不可见元素)。

例子就可以直接参考前面的那个,这里就不单独举例了。

  

数据虚拟化:

UI虚拟化可以解决渲染UI控件所需要较多的时间和内存的问题,但是还是有可以优化的空间,那就是所有的数据仍然都加载到了内存中了。我们仍然可以采用和UI虚拟化一样的优化方案:不加载所有数据到集合,只加载用户可见部分。数据虚拟化本身并不受WPF所支持,不过当我们的Panel实现IScrollInfo接口了之后,就可以精确感知滚动条了,实现数据虚拟化也不是难事。

一般来说,我们很少使用数据虚拟化,主要的原因是它大多数的时候只能减少很少一点内存占用,反而带来了较大的代码复杂度, 一般是认为得不偿失的。

不过,有的时候,我们的数据是来自于外部RPC访问,这个时候数据虚拟化就有意义了,考虑如下两个场景:

  1. 新闻客户端,数据来源是来自于远程的Rest服务,但是它的接口是分页获取的,只能每次获取50条,总共却可能有100页。
  2. 图片浏览器,图片不是来自于本地,而是来自于图片服务网站。

第一个例子就是比较典型的数据虚拟化的应用场景了,如果一开始就加载所有100页新闻就需要花费大量时间了。第二个例子则是部分数据虚拟化,图片信息无需虚拟化,但图片呈现需要虚拟化,只是在需要呈现的时候才从网络下载。

 

目录
相关文章
|
6月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
372 0
|
2月前
|
搜索推荐 前端开发 C#
推荐7款美观且功能强大的WPF UI库
推荐7款美观且功能强大的WPF UI库
|
3月前
|
C# 开发者 Windows
一款基于Fluent设计风格、现代化的WPF UI控件库
一款基于Fluent设计风格、现代化的WPF UI控件库
|
3月前
|
vr&ar C# 图形学
WPF与AR/VR的激情碰撞:解锁Windows Presentation Foundation应用新维度,探索增强现实与虚拟现实技术在现代UI设计中的无限可能与实战应用详解
【8月更文挑战第31天】增强现实(AR)与虚拟现实(VR)技术正迅速改变生活和工作方式,在游戏、教育及工业等领域展现出广泛应用前景。本文探讨如何在Windows Presentation Foundation(WPF)环境中实现AR/VR功能,通过具体示例代码展示整合过程。尽管WPF本身不直接支持AR/VR,但借助第三方库如Unity、Vuforia或OpenVR,可实现沉浸式体验。例如,通过Unity和Vuforia在WPF中创建AR应用,或利用OpenVR在WPF中集成VR功能,从而提升用户体验并拓展应用功能边界。
62 0
|
3月前
|
C# 开发者 设计模式
WPF开发者必读:命令模式应用秘籍,轻松简化UI与业务逻辑交互,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,命令模式是简化UI与业务逻辑交互的关键技术,通过将请求封装为对象,实现UI操作与业务逻辑分离,便于代码维护与扩展。本文介绍命令模式的概念及实现方法,包括使用`ICommand`接口、`RelayCommand`类及自定义命令等方式,并提供示例代码展示如何在项目中应用命令模式。
44 0
|
3月前
|
开发者 C# 存储
WPF开发者必读:样式与模板的艺术,轻松定制UI外观,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,样式与模板是实现美观界面与一致性的关键工具。样式定义了控件如字体、颜色等属性,而模板则允许自定义控件布局与子控件,两者均可存储于`.xaml`文件中。本文介绍了样式与模板的基础知识,通过示例展示了如何创建并应用它们来改变按钮的外观,从而提升用户体验。
62 0
|
4月前
|
C# Windows
一款开源、免费、现代化风格的WPF UI控件库
一款开源、免费、现代化风格的WPF UI控件库
136 0
|
6月前
|
前端开发 C# 索引
浅谈WPF之UI布局
一个成功的软件,离不开人性化的UI设计,如何抓住用户第一视觉,让用户产生依赖感,合适优雅的布局必不可少。本文以一些简单的小例子,简述WPF中布局 面板 控件的使用,仅供学习分享使用,如有不足之处,还请指正。
97 1
|
6月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
134 1
|
3月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件