当前位置: 首页 > ai >正文

WPF 性能 UI 虚拟化 软件开发人员的思考

    UI 虚拟化是 WPF 采用的一项技术,框架会仅创建用户可见的 UI 元素。例如,如果 ListView 中有 1000 个文本块控件,但您只能查看其中的 10 个,那么 VisualTree 中也只会显示 10 个文本块。向下滚动时,不再可见的元素将被丢弃,并创建下一组可见项。这种虚拟化技术在速度和内存方面都带来了显著的 UI 性能优势。

    WPF 中的 UI 虚拟化由 VirtualizingStackPanel 提供,并且默认启用。您可以像图中所示,在 StackPanel 上显式指定 UI 虚拟化的开启/关闭。

<StackPanel VirtualizingStackPanel.IsVirtualizing="True"></StackPanel>

    请注意,UI 虚拟化仅在 ItemsControl 生成其自身模板时才有效。如果生成了模板,然后添加虚拟化,则虚拟化将被禁用。因此,UI 虚拟化的缺点在于它在某些情况下是禁用的。其中一种情况是您覆盖 ItemsPanelTemplate 或 ItemsControl 的模板。在这种情况下,如果 ItemsPanelTemplate 由开发人员自定义,则 UI 虚拟化将被禁用。因此,如果您的 ItemsControl 显示已加载的数据,那么您就有麻烦了。为了避免这种情况并在覆盖 ItemsPanelTemplate 的情况下启用 UI 虚拟化,我们需要使用 VirtualizingStackPanel。

    为了测试启用和禁用虚拟化的效果,我编写了一个简单的应用程序。它有一个列表视图,其 itempanel 模板已自定义 - 首先使用普通的 StackPanel,然后使用 VirtualizingStackPanel。它从名称列表中加载文本块。

    当我在列表中运行包含 1000000 个项目的测试时,在没有虚拟化的情况下,程序根本无法启动。它占用了近 2 GB 的内存,而且根本无法运行。所以我不得不终止它。然后,启用虚拟化后,程序很快就启动了,内存占用只有 200MB。在此之前,让我们先看看我使用的 XAML 和后台代码。它还会向您展示如何自定义 ItemsPanelTemplate 和使用 VirtualizingStackPanel。

<Window x:Class="NiceControlsTest.Window2" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window2"Height="300"Width="300"Loaded="Window_Loaded"> 
<Grid> 
<ListView ItemsSource="{BindingNames}"Name="lv"> 
<ListView.ItemsPanel> 
<ItemsPanelTemplate> 
<!--<StackPanel/>
如果使用 StackPanel,则消耗的内存将超过 2GB,并且速度非常慢。
--> 
<VirtualizingStackPanel> 
<!--内存占用仅 200 mb--> 
</VirtualizingStackPanel> 
</ItemsPanelTemplate> 
</ListView.ItemsPanel> 
<ListView.ItemTemplate> 
<DataTemplate> 
<TextBlock Text="{Binding}"/> 
</DataTemplate> 
</ListView.ItemTemplate> 
</ListView> 

</Grid> 
</Window>

背后的代码非常简单:

public partial class Window2 : Window 

public List<string> Names { get; set; } 
private DateTime start; 
public Window2() 

start = DateTime.Now; 
InitializeComponent(); 
Names = new List<string>(); 
for (int i = 0; i < 10000; i++) 
Names.Add("Name : " + i); 
lv.DataContext = this; 

private void Window_Loaded(object sender, RoutedEventArgs e) 

MessageBox.Show((DateTime.Now - start).TotalSeconds.ToString()); 

    经过精确测量了从窗口构建到加载的时间。结果发现,仅使用 StackPanel 时,对于使用的 10000 个项目(为了加快测量速度,减少了项目数量),内存占用约为 176 MB,启动时间为 7 到 10 秒。而使用 VirtualizingStackPanel 时,内存占用略高于 16 MB,启动时间为 0.3 到 0.8 秒。

    个人认为这对我们开发人员来说非常有利。我们可以设计和开发大型高负载图形应用程序,而无需担心进行某种程度的优化。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。 

http://www.xdnf.cn/news/5096.html

相关文章:

  • 阿里云OSS+CDN自动添加文章图片水印配置指南
  • 第五天 车载系统安全(入侵检测、OTA安全) 数据加密(TLS/SSL、国密算法)
  • Kubernetes生产实战(十四):Secret高级使用模式与安全实践指南
  • 解决mybatisplus主键无法自增的问题
  • uniapp-商城-50-后台 商家信息
  • 如何用AWS Lambda构建无服务器解决方案:实战经验与场景解析
  • 第十八节:图像梯度与边缘检测-Scharr 算子
  • OpenLayers 精确经过三个点的曲线绘制
  • opencv处理图像(二)
  • 抖音视频去水印怎么操作
  • Taro 编译不平不同平台小程序
  • 1.2.2.1.4 数据安全发展技术发展历程:高级公钥加密方案——同态加密
  • Java数据结构——二叉树
  • 进程间通信--管道【Linux操作系统】
  • Maven 插件配置分层架构深度解析
  • 滚珠丝杆在工作中损耗会影响什么?
  • 【计算机视觉】3DDFA_V2中表情与姿态解耦及多任务平衡机制深度解析
  • Android Compose 框架物理动画之捕捉动画深入剖析(29)
  • 封装 RabbitMQ 消息代理交互的功能
  • mac u盘重装mac10.15Catalina系统
  • 1.短信登录
  • 数据库故障排查全攻略:从实战案例到体系化解决方案
  • expo多网络请求设定。
  • Jmeter中的BeanShell如何使用?
  • MySQL 从入门到精通(三):日志管理详解 —— 从排错到恢复的核心利器
  • 01背包类问题
  • 基于大模型与异步技术的股票分析系统实现
  • 在 Flink + Kafka 实时数仓中,如何确保端到端的 Exactly-Once
  • Stable Diffusion进阶之Controlnet插件使用
  • python连接sqllite数据库工具类