跳到主要内容
版本:11.0.0

布局

面板(Panel)

Avalonia 包含一组派生自 Panel 的元素。这些 Panel 元素可实现许多复杂的布局。例如,可以使用 StackPanel 元素轻松地堆叠元素,而使用 Canvas 则可以实现更复杂和自由流动的布局。

以下表格总结了可用的 Panel 控件:

名称描述
Panel将所有子元素布局以填充 Panel 的边界
Canvas定义一个区域,您可以在其中使用相对于 Canvas 区域的坐标明确定位子元素
DockPanel定义一个区域,其中您可以相对于彼此将子元素水平或垂直地排列
Grid定义由列和行组成的灵活网格区域
RelativePanel将子元素相对于其他元素或面板本身排列
StackPanel将子元素排列成一行,可以是水平或垂直方向
WrapPanel将子元素按从左到右的顺序放置,当内容到达容器框的边缘时,将在下一行中断。后续排序顺序是顺序从上到下或从右到左,这取决于 Orientation 属性的值。

在 WPF 中,Panel 是一个抽象类,通常使用没有行/列的 Grid 来布局多个控件以填充可用空间。在 Avalonia 中,Panel 是一个可用的控件,其布局行为与没有行/列的 Grid 相同,但运行时占用更少的资源。

元素边界框

在考虑 Avalonia 中的布局时,了解包围所有元素的边界框很重要。布局系统处理的每个 Control 可以看作是一个矩形,该矩形被插入布局。Bounds 属性返回元素布局分配的边界。矩形的大小通过计算可用的屏幕空间、任何约束的大小、布局特定属性(如 margin 和 padding)以及父 Panel 元素的个体行为来确定。处理这些数据,布局系统能够计算特定 Panel 的所有子元素的位置。重要的是要记住,定义在父元素上的大小特性,例如 Border 上的特性,会影响其子元素。

布局系统

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

每次子控件更改其位置时,它都有可能触发布局系统的新传递。因此,了解可以调用布局系统的事件很重要,因为不必要的调用可能会导致应用程序性能下降。下面描述了在调用布局系统时发生的过程。

  1. 子 UIElement 通过首先测量其核心属性来开始布局过程。
  2. 评估在 Control 上定义的大小属性,例如 WidthHeightMargin
  3. 应用 Panel 特定的逻辑,例如 Dock 方向或堆叠的 Orientation
  4. 在所有子元素进行测量后,进行内容的排列。
  5. 在屏幕上绘制 Children 集合。
  6. 如果向集合中添加了其他 Children,则再次调用此过程。

此过程及其调用方式在以下部分中有更详细的定义。

测量和排列子元素

布局系统对 Children 集合的每个成员完成两个传递:测量传递和排列传递。每个子 Panel 提供其自己的 MeasureOverrideArrangeOverride 方法,以实现其自己的特定布局行为。

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

首先,评估 Visual 的本机大小属性,例如 ClipIsVisible。这将生成传递给 MeasureCore 的约束。

然后,处理影响约束值的框架属性。这些属性通常描述底层 Control 的大小特性,例如其 HeightWidthMargin。每个这些属性都可以改变显示元素所需的空间。然后,使用约束调用 MeasureOverride

由于 Bounds 是计算值,因此您应该注意,由于布局系统的各种操作,它可能会发生多次或增量的报告更改。布局系统可能正在为子元素计算所需的测量空间、父元素的约束等。

测量传递的最终目标是让子元素确定其 DesiredSize,这在 MeasureCore 调用期间发生。MeasureDesiredSize 值存储以在内容排列传递中使用。

排列传递从调用 Arrange 方法开始。在排列传递期间,父 Panel 元素生成表示子元素边界的矩形。该值传递给 ArrangeCore 方法进行处理。

ArrangeCore 方法评估子元素的 DesiredSize,并评估任何可能影响元素渲染大小的附加 marginArrangeCore 生成一个排列大小,将其作为参数传递给 PanelArrangeOverride 方法。ArrangeOverride 生成子元素的 finalSize。最后,ArrangeCore 方法对边距和对齐等偏移属性进行最后评估,并将子元素放置在其布局插槽中。子元素不必(也经常不会)填充整个分配的空间。然后,将控件返回给父 Panel,布局过程完成。

本节内容