Panel的顺序在渲染时间和性能方面最有效?

Rac*_*hel 120 wpf performance rendering panel

很多时候,多个面板适合我想要的布局,但我知道不同面板类型的渲染时间有所不同.

例如,MSDN声明

相对简单Panel,例如Canvas,可以具有比更复杂的更好的性能Panel,例如Grid.

那么在渲染时间和性能方面,WPF面板的最高效率是多少?

WPF小组:

  • Canvas
  • DockPanel
  • Grid
  • UniformGrid
  • StackPanel
  • WrapPanel
  • VirtualizingPanel/VirtualizingStackPanel

我很确定我在网上看到了这个列表,但我现在找不到它.

我正在寻找的理想答案将为我提供一个面板列表,按照他们最快速渲染的顺序.我知道儿童的数量是面板效率的一个重要因素,因此为了这个问题,假设每个面板只有一对Label/ TextBox一对.

此外,我想要一个例外列表,例如特定面板,它们在某些条件下比其他面板表现更好.

更新

总结基于下面接受的答案,面板性能基于子项的数量和布局,但一般来说,从最快到最慢的列表是:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

此外,如果有许多项目并不总是适合屏幕,则应始终使用VirtualizingPanel/ VirtualizingStackPanel.

在强烈选择此列表中的项目之前,我强烈建议您阅读下面接受的答案以获取更多详细信息.

N_A*_*N_A 123

我认为描述每个面板的性能特征比尝试进行绝对相对性能比较更简洁和易懂.

WPF在渲染内容时进行两次传递:测量和排列.每个面板对于这两个通道中的每一个具有不同的性能特征.

测量通过的性能受到面板适应拉伸的能力的影响(使用对齐(或者在情况下为自动Grid),然后是拉伸或自动调整尺寸的儿童的数量).编排通行证的表现受到不同儿童的布局位置之间的相互作用的复杂性的影响,当然还有儿童的数量.

有时,给定的面板不容易适应所需的布局.我创建了一个控件,需要任意数量的项目,每个项目位于可用空间的特定百分比.没有默认控件执行此操作.试图让他们这样做(通过绑定到父级的实际大小)会导致可怕的性能.我创建了一个基于Canvas的布局面板,它以最少的工作实现了我想要的结果(我复制了画布的源并修改了大约20行).

可用面板:

  • 帆布

    定义一个区域,您可以在其中通过相对于"画布"区域的坐标显式定位子元素.

    由于每个项目都是静态分配的位置,因此Canvas在排列过程中具有所有面板的最佳性能.测量通过也具有优异的性能,因为在该面板中没有拉伸的概念; 每个孩子只使用其原生大小.

  • DockPanel中

    定义一个区域,您可以在其中相对于彼此水平或垂直排列子元素.

    Dockpanel有一个非常简单的布局方案,其中项目相对于添加的上一个项目逐个添加.默认情况下,高度或宽度由项目的原始大小确定(分别基于顶部/底部与左/右),Dock如果未定义宽度或高度,则另一个方向由属性确定.中等到快速测量通过和中到快速通过.

  • 定义由列和行组成的灵活网格区域.

    如果使用比例尺寸或自动尺寸调整,这可能是性能最高的面板.计算子项目大小可以是项目的本机大小和网格指定的布局的复杂组合.布局也是所有面板中最复杂的.测量通过的慢到中等性能和布置通过的慢到中等性能.

  • StackPanel中

    将子元素排列成可以水平或垂直定向的单个行.

    StackPanel使用与其方向相反方向的原生或相对大小以及在其方向上的原生大小来测量其子级(对齐在此方向上没有任何作用).这使它成为这一领域的中级表演者.安排通行证很简单,只是按顺序布置项目.可能是这次传球的第二好成绩.测量通过的中等性能和布局通过的快速性能.

  • VirtualizingPanel

    为Panel元素提供虚拟化其子数据集合的框架.这是一个抽象类.

    用于实现自己的虚拟化面板的基类.仅加载可见项目以防止不必要地使用内存和处理器.对于多组物品,性能更高.由于边界检查,适合屏幕的项目可能性能稍差.SDK只提供了这个的一个子类VirtualizingStackPanel.

  • WrapPanel

    将子元素从左到右定位在顺序位置,将内容分解到包含框边缘的下一行.后续排序从上到下或从右到左依次发生,具体取决于Orientation属性的值.

    度量过程是一个有点复杂的过程,其中特定行的最大项目确定行的高度,然后该行上的每个项目使用其原始高度(如果有的话)或行的高度.布局传递很简单,将每个项目一个接一个地放在一行上,然后在没有足够空间容纳下一个项目时继续到下一行.中等绩效测量通过.安排通过中等到快速的性能.

参考文献:

尽可能使用最高效的面板

布局过程的复杂性直接基于您使用的Panel派生元素的布局行为.例如,Grid或StackPanel控件提供比Canvas控件更多的功能.功能性更大增加的代价是性能成本的更大增加.但是,如果您不需要Grid控件提供的功能,则应使用成本较低的替代方法,例如Canvas或自定义面板.

优化性能:布局和设计

布局系统为Children集合的每个成员完成两次传递,一个度量传递和一个排列传递.每个子Panel都提供自己的MeasureOverride和ArrangeOverride方法来实现自己的特定布局行为.

在测量过程中,将评估Children集合的每个成员.该过程从调用Measure方法开始.在父Panel元素的实现中调用此方法,并且不必显式调用此方法以进行布局.

首先,评估UIElement的原生大小属性,例如Clip和Visibility.这将生成一个名为constraintSize的值,该值将传递给MeasureCore.

其次,处理FrameworkElement上定义的框架属性,这会影响constraintSize的值.这些属性通常描述底层UIElement的大小特征,例如高度,宽度,边距和样式.这些属性中的每一个都可以更改显示元素所需的空间.然后使用constraintSize作为参数调用MeasureOverride.

注意高度和宽度以及ActualHeight和ActualWidth的属性之间存在差异.例如,ActualHeight属性是基于其他高度输入和布局系统的计算值.该值由布局系统本身根据实际渲染过程设置,因此可能略微落后于属性的设置值,例如高度,这是输入更改的基础.因为ActualHeight是一个计算值,所以您应该知道,由于布局系统的各种操作,可能会有多个或增量报告的更改.布局系统可以计算子元素所需的度量空间,父元素的约束等等.度量传递的最终目标是让孩子确定其DesiredSize,它发生在MeasureCore调用期间.DesiredSize值由Measure存储,以便在内容排列过程中使用.

排列过程以调用Arrange方法开始.在排列过程中,父Panel元素生成一个矩形,表示子项的边界.此值将传递给ArrangeCore方法进行处理.

ArrangeCore方法计算子项的DesiredSize并计算可能影响元素的呈现大小的任何其他边距.ArrangeCore生成一个arrangeSize,它作为参数传递给Panel的ArrangeOverride方法.ArrangeOverride生成孩子的finalSize.最后,ArrangeCore方法对偏移属性(如边距和对齐)进行最终评估,并将子项放在其布局槽中.孩子不必(通常也不)填满整个分配的空间.然后将控制权返回到父面板,并完成布局过程.

测量和安排儿童


小智 11

也许会对你有所帮助.
不仅适用于面板,还适用于您希望在WPF中创建的每个应用程序.

它总结了WPF绘图和测量性能.

它还具有您要定位的不同操作系统的绘图测试应用程序,结果和结论信息.


Eri*_*ick 7

您提到的面板是布局面板,因此布局系统的简要概述表明,它可能不仅仅是最有效面板的简单列表,而是如何使用对效率和性能影响最大的面板.

LayoutSystem_Overview:

最简单的布局是一个递归系统,它导致元素的大小,位置和绘制.更具体地说,布局描述了测量和排列Panel元素的Children集合成员的过程.布局是一个密集的过程.Children集合越大,必须进行的计算次数越多.还可以基于拥有集合的Panel元素定义的布局行为来引入复杂性.相对简单的Panel(如Canvas)可以比更复杂的Panel(如Grid)具有更好的性能.

每次子UIElement改变其位置时,它都有可能触发布局系统的新传递.因此,理解可以调​​用布局系统的事件非常重要,因为不必要的调用会导致应用程序性能不佳.以下描述调用布局系统时发生的过程.

1.子UIElement首先测量其核心属性,从而开始布局过程.

2.评估FrameworkElement上定义的大小调整属性,例如宽度,高度和边距.

3.应用面板特定的逻辑,例如Dock方向或堆叠方向.

4.在测量所有儿童后安排内容.

5.儿童系列画在屏幕上.

6.如果将其他Children添加到集合,应用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渲染速度的方法

  1. 缓存一切.画笔,颜色,几何图形,格式化文本,字形.(例如,我们有两个类:RenderTools和TextCache渲染每个单元地址的过程,以这两个类的共享实例因此,如果两个图具有相同的文字,只是执行一次及其制备.)
  2. 冻结Freezable,如果您计划长时间使用它.特别是几何形状.复杂的解冻几何执行HitTest极其缓慢.
  3. 选择每种基元的最快渲染方式.例如,大约有6种文本渲染方式,但最快的是DrawingContext.DrawGlyphs.
  4. 启用容器回收.虚拟化带来了许多性能改进,但容器将被处理并重新创建,这是默认设置.但是,通过设置VirtualizingStackPanel.VirtualizationMode ="Recycling",您可以通过回收容器获得更高的性能
  5. 这里:应用程序可以支持的嵌套量没有实际限制,但是,通常最好将应用程序限制为仅使用实际所需布局所需的那些面板.在许多情况下,由于其作为布局容器的灵活性,可以使用Grid元素而不是嵌套面板.这可以通过将不必要的元素保留在树之外来提高应用程序的性能.

  • 这个答案几乎完全是从其他来源复制和粘贴,一些是未归因的.如果你把它削减到相关的部分,正确地归因于所有来源并试图更直接地回答问题,那会好得多. (2认同)
  • @mydogisbox答案是信息汇编,你可以补充一下你在答案中使用的许多相同网站.如果不考虑改变表现的其他方面可能导致答案不完整或者提问者仍有其他问题,所以我选择将其包括在内.虽然雷切尔拥有惊人的21.7万代表和大量的WPF经验可能已经知道这些信息,但正在寻找这个问题的其他人可能希望获得这些额外的和重要的信息以及答案. (2认同)