WPF虚拟化技术分为UI 虚拟化和数据虚拟化

第一种方法被称为"UI 虚拟化"。支持虚拟化用户界面的控件是足够聪明来创建只显示的是实际在屏幕上可见的数据项目所需的 UI 元素。例如,假设我们有一个滚动的列表框是绑定到 1,000,000 项目的数据,但在任何时候是可见的只有 100。没有 UI 虚拟化,列表框将创建 100 万 ListBoxItems — — 一个缓慢的过程 — — 并包括他们在 UI 中,即使只有一百人是可见。与用户界面虚拟化,另一方面,列表框中将只创建 100 ListBoxItems (或更多,从而提高滚动性能)。

第二种方法,被称为"虚拟化的数据,"更进了一步。使用数据虚拟化的控件不会加载到内存的所有数据项。相反,它只加载显示所需的。在我们上面的列表框示例,使用数据的虚拟化解决方案将只保留约 100 个数据项目在内存中在任何给定时间。

VirtualizingStackPanel.IsVirtualizing 附加属性

VirtualizingStackPanel.VirtualizationMode 附加属性


默认情况下, VirtualizingStackPanel 创建每个可见项的项容器以及丢弃,当不再需要时 (例如,当项滚动到视图之外时)。  当 ItemsControl 包含许多项目时,会创建并放弃项容器处理会对性能产生负面影响。  当 VirtualizingStackPanel.VirtualizationMode 设置为 Recycling时, VirtualizingStackPanel 重用项目容器而不是每次创建新的。
 <StackPanel>

   <StackPanel.Resources>
<src:LotsOfItems x:Key="data"/>
</StackPanel.Resources> <ListBox Height="" ItemsSource="{StaticResource data}"
VirtualizingStackPanel.VirtualizationMode="Recycling" /> </StackPanel>

容器回收

.NET 3.5 SP1 支持 UI 容器的重用已经在内存中。例如,想象当加载一个列表框,则 30 ListBoxItems 创建要显示的可见数据。当用户滚动列表框,而不是丢弃滚动到视图之外的 ListBoxItems 和创建新的数据项的滚动到视图,WPF 会重用现有的 ListBoxItems。此结果中显著的性能改进与以前的版本相比,因为它减少了的时间花了初始化 ListBoxItems。因为垃圾回收不是瞬时的它也减少了 ListBoxItems 存储器中的数一次。

您可以启用容器回收通过在您的控件上设置附加的属性"VirtualizingStackPanel.VirtualizationMode"到"Recycling":

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

为了保持向后兼容与早期版本的行为,容器回收的默认被禁用的 (默认的 VirtualizationMode 是"Standard")。作为一个经验法则,我建议将此属性设置每次创建一个控件,需要滚动以显示数据的项目。

延迟滚动

"递延滚动"是一种功能,允许用户拖动滚动条滑块周围而无需更改显示的项,直到滚动条滑块被释放。这提高了应用程序的感知的响应滚动时显示的项使用复杂的模板,但当然,用户不能看到他们在滚动的项目。

与.NET 3.5 SP1 中,它有可能启用延迟滚动通过在控件上设置附加的属性:

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

分层数据

在.NET 3.5 SP1 中,WPF 团队扩展用户界面虚拟化到 TreeView 通过向 VirtualizingStackPanel 添加对分层数据的支持。因此,容器回收和上面讨论的递延滚动功能也适用于分层数据。默认情况下,在 TreeView 中禁用用户界面虚拟化 — — 在这里是如何启用它:

<TreeView VirtualizingStackPanel.IsVirtualizing="True" …

这个属性是非常有用的不只是为树视图,但对于任何控件的使用 VirtualizingStackPanel 和那不设置 IsVirtualizing 为 true (例如 ItemsControl)。列表框中已经将 IsVirtualizing 设置为 True,默认情况下,这样就无需显式设置它。

局限性

.NET 3.5 SP1 固定很多以前的限制在 UI 虚拟化,但仍然是一对夫妇仍然:

  • ScrollViewer 目前允许两种滚动模式: 平滑滚动的像素 (CanContentScroll = false) 或离散按项目滚动 (CanContentScroll = true)。目前 WPF 支持用户界面虚拟化,只有当按项目滚动。基于像素的滚动也被称为"物理滚动"和基于项目的滚动也被称为"逻辑滚动"。
  • 使用数据绑定"分组"功能时,那里是没有用户界面虚拟化的支持。

这些真的是相同的限制。如果你看看默认的样式列表框、 列表视图和组合框,你会发现下面的触发器:

 <Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>

分组执行假定每个组是一个单独的项目中包含它的 ItemsControl。因为每个组可以 (并且通常所做的) 有很多子项目,按项目滚动将结果真的不好的用户体验 — — 滚动下来有点会导致一大跳下一组的顶部。这就是为什么团队决定切换到基于像素滚动显示分组数据时。不幸的后果是没有用户界面虚拟化支持的分组时。

WPF Virtualization的更多相关文章

  1. [WPF]WPF Data Virtualization和UI Virtualization

    这篇博客将介绍WPF中的虚拟化技术. 1. Data Virtualization 通常情况下我们说数据虚拟化是指数据源没有完全加载,仅加载当前需要显示的数据呈现给用户.这种场景会让我们想到数据分页显 ...

  2. 精通 WPF UI Virtualization (提升 OEA 框架中 TreeGrid 控件的性能)

    原文:精通 WPF UI Virtualization (提升 OEA 框架中 TreeGrid 控件的性能) 本篇博客主要说明如何使用 UI Virtualization(以下简称为 UIV) 来提 ...

  3. OpenExpressApp:精通 WPF UI Virtualization

    原文:OpenExpressApp:精通 WPF UI Virtualization 本篇博客主要说明如何使用 UI Virtualization(以下简称为 UIV) 来提升 OEA 框架中 Tre ...

  4. [WPF系列]-基础系列 TabControl应用

    引言 Tabcontrol控件也是我们在项目中经常用到的一个控件,用它将相关的信息组织在一起分类显示. 简介     ========================================= ...

  5. wpf DataGrid CheckBox列全选

    最近在wpf项目中遇到当DataGrid的header中的checkbox选中,让该列的checkbox全选问题,为了不让程序员写自己的一堆事件,现写了一个自己的自定义控件 在DataGrid的 &l ...

  6. wpf 如果列表加载超多数据变的卡顿时,使用VirtualizingStackPanel

    如果列表加载超多数据变的卡顿时 <ListBox > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Virt ...

  7. WPF相关资料集锦

    微软官方资料 .NET Framework源代码 https://referencesource.microsoft.com/ 微软官方文档 https://docs.microsoft.com/en ...

  8. wpf datagrid performance

    http://stackoverflow.com/questions/1704512/wpf-toolkit-datagrid-scrolling-performance-problems-why h ...

  9. 关于WPF你应该知道的2000件事

    原文 关于WPF你应该知道的2000件事 以下列出了迄今为止为WPF博客所知的2,000件事所创建的所有帖子. 帖子总数= 1,201 动画 #7 - 基于属性的动画 #686 - 使用动画制作图像脉 ...

随机推荐

  1. WCF服务用户名密码访问

    有2种方式, 第一直接在程序中指定用户名密码,配置调用 private void BtnSearch_Click(object sender, EventArgs e) { try { var cli ...

  2. 字符串(String)

    字符串是由字符组成的数组,但在JavaScript中字符串是不可变的:可以访问字符串任意位置的文本,但是JavaScript并未提供修改已知字符串内容的方法. 常见功能: obj.length     ...

  3. Material使用09 MdCheckboxModule、MdMenuModule、MdTooltipModule

    1 MdCheckboxModule的使用 md-checkbox 实现的功能和  <input type="checkbox">  相同,只不过 md-checkbo ...

  4. maven 打JAR包资源文件指定路径与文件读取

    1.配置RESOURCES节点 有时会遇到maven打包后找不到资源文件了,其实这时候路径发生了变化,为了确保打包后路径不发生变化,指定一个固定的路径,请看下面配置 <build> ... ...

  5. hadoop-2.3.0-cdh5.1.0完全分布式搭建(基于centos)

    先参考:<hadoop-2.3.0-cdh5.1.0伪分布安装(基于centos)> http://blog.csdn.net/jameshadoop/article/details/39 ...

  6. centos6.x禁用ipv6的方法

    注意可能有两个网卡的情况,修改当前网卡才有效. cd /etc/sysconfig/network-scripts/ ls ifcfg-Auto_eth0 ifcfg-eth0 现在ipv6没流行,几 ...

  7. IIS 找不到.net framework 4.0/4.5程序池

    通常情况下是因为没注册造成的,也有可能跟操作系统有关系 以管理员身份运行cmd   打开我的电脑 C:\Windows\System32\cmd.exe,右键以管理员身份运行 然后:C:\WINDOW ...

  8. JSONCPP学习笔记

    基本使用 使用jsoncpp库解析.修改.打印JSON串 源文件 $ cat main.cpp #include <iostream> #include "json/json.h ...

  9. Python 爬虫笔记

    urllib python3 与 python2 的urllib很不一样,之前urllib2的方法基本上都变成了python3里的urllib.request模块中 import urllib.req ...

  10. 初等变换求 |A| % Mod & A- % Mod & A* % Mod(模板)

    // |A| * A- = A* (伴随矩阵) = 逆矩阵 * 矩阵的值 #include<cstdio> #include<cstring> #include<cstd ...