您提到的面板是“布局”面板,因此对布局系统的简要概述表明,它可能不仅仅是最有效的面板的简单列表,而是如何使用对效率和性能影响最大的面板。
LayoutSystem_Overview:
最简单的说,布局是一种递归系统,可导致元素的大小,位置和绘制。更具体地说,布局描述了测量和安排Panel元素的Children集合的成员的过程。布局是一个密集的过程。Children集合越大,必须进行的计算数量就越大。还可以根据拥有该集合的Panel元素定义的布局行为来引入复杂性。相对简单的面板(例如Canvas)比更复杂的面板(例如Grid)具有明显更好的性能。
子UIElement每次更改其位置时,都有可能触发布局系统进行新的传递。因此,了解可调用布局系统的事件很重要,因为不必要的调用会导致较差的应用程序性能。下面描述了调用布局系统时发生的过程。
1.子UIElement首先通过测量其核心属性来开始布局过程。
2.评估在FrameworkElement上定义的大小调整属性,例如Width,Height和Margin。
3.应用特定于面板的逻辑,例如Dock方向或堆叠方向。
4.在对所有孩子进行测量之后,才安排内容。
5.在屏幕上绘制儿童集合。
6.如果将其他子级添加到集合,应用了LayoutTransform或调用UpdateLayout方法,则再次调用该过程。
有关测量和安排子项的更多信息,请参见LayoutSystem_Measure_Arrange。
LayoutSystem_Performance:
布局是一个递归过程。在每次调用布局系统时,都会处理Children集合中的每个子元素。因此,在不必要时应避免触发布局系统。以下注意事项可以帮助您获得更好的性能。
注意哪些属性值更改将迫使布局系统进行递归更新。
其依赖项的值可能导致布局系统初始化的依赖项属性用公共标志标记。AffectsMeasure和AffectsArrange提供了有关哪些属性值更改将迫使布局系统进行递归更新的有用线索。通常,任何可能影响元素边框大小的属性都应将AffectsMeasure标志设置为true。有关更多信息,请参见依赖项属性概述。
如果可能,请使用RenderTransform而不是LayoutTransform。
LayoutTransform是影响用户界面(UI)内容的非常有用的方法。但是,如果变换的效果不必影响其他元素的位置,则最好改用RenderTransform,因为RenderTransform不会调用布局系统。LayoutTransform应用其转换并强制进行递归布局更新以考虑受影响元素的新位置。
避免不必要地调用UpdateLayout。
UpdateLayout方法强制进行递归布局更新,通常不需要这样做。除非您确定需要完全更新,否则请依赖布局系统为您调用此方法。
当使用较大的Children集合时,请考虑使用VirtualizingStackPanel而不是常规的StackPanel。
通过虚拟化子级集合,VirtualizingStackPanel仅将对象当前保留在父级ViewPort内的内存中。结果,在大多数情况下,性能都得到了显着改善。
优化性能:布局和设计:本文详细介绍如何有效地构建树,并根据其复杂性给出面板的简单列表
画布(最少的组合=更有效和更好的性能)
格
其他小组(更复杂=效率较低且性能较差)
需要注意的其他性能注意事项: 提高WPF UI渲染速度的方法
- 缓存所有内容。笔刷,颜色,几何形状,格式化文本,字形。(例如,我们有两个类:RenderTools和TextCache。每个单元的渲染过程将地址分配给这两个类的共享实例。因此,如果两个图表具有相同的文本,则其准备仅执行一次。)
- 如果打算长时间使用,请冻结Freezable。特别是几何形状。复杂的未冻结几何图形执行HitTest的速度非常慢。
- 选择最快的渲染每个图元的方法。例如,大约有6种文本呈现方式,但是最快的是DrawingContext.DrawGlyphs。
- 启用容器回收。虚拟化带来了很多性能改进,但是容器将被处置并重新创建,这是默认设置。但是通过设置VirtualizingStackPanel.VirtualizationMode =“ Recycling”,可以通过回收容器来获得更高的性能。
- 从这里开始:对您的应用程序可以支持的嵌套数量没有实际限制,但是,通常最好将您的应用程序限制为仅使用所需布局实际需要的那些面板。在许多情况下,由于其作为布局容器的灵活性,因此可以使用Grid元素代替嵌套面板。通过将不必要的元素保留在树中,可以提高应用程序的性能。