📐布局
面板
Avalonia 包含了一组派生自 Panel 的元素。这些 Panel 元素使得许多复杂的布局变得容易实现。例如,可以使用 StackPanel 元素轻松地堆叠元素,而使用 Canvas 则可以实现更复杂、自由流动的布局。
以下表格总结了可用的 Panel 控件:
Panel
将所有子元素布局以填充 Panel 边界的区域。
Canvas
定义一个区域,在此区域内可以通过相对于 Canvas 区域的坐标显式定位子元素。
DockPanel
定义一个区域,在此区域内可以相对于彼此按水平或垂直方向排列子元素。
Grid
定义一个灵活的网格区域,由列和行组成。
RelativePanel
相对于其他元素或面板本身布置子元素。
StackPanel
将子元素布置为单行,可以水平或垂直方向定向。
WrapPanel
将子元素按顺序从左到右排列,当内容超出容器框的边缘时,将其断开到下一行。随后的排序顺序按顺序从上到下或从右到左,取决于方向属性的值。
在 WPF 中,Panel 是一个抽象类,并且通常使用不带行/列的 Grid 布置多个控件以填充可用空间。在 Avalonia 中,Panel 是一个可用的控件,具有与不带行/列的 Grid 相同的布局行为,但运行时占用更少的资源。
元素边界框
在 Avalonia 中考虑布局时,了解包围所有元素的边界框非常重要。每个被布局系统使用的 Control 可以看作是一个矩形,插入到布局中。Bounds 属性返回元素布局分配的边界。矩形的大小通过计算可用屏幕空间、约束的大小、布局特定的属性(如边距和填充)以及父级 Panel 元素的个体行为来确定。通过处理这些数据,布局系统能够计算出特定 Panel 的所有子元素的位置。需要记住的是,在父元素上定义的大小特征,例如 Border,会影响其子元素。
布局系统
简单来说,布局是一个递归系统,它会导致元素被大小和位置确定并最终绘制。更具体地说,布局描述了对 Panel 元素的 Children 集合的成员进行测量和排列的过程。布局是一个非常耗费计算资源的过程。Children 集合越大,需要进行的计算次数就越多。同时,所拥有的 Children 集合的 Panel 元素所定义的布局行为也会引入复杂性。一个相对简单的 Panel,比如 Canvas,在性能上可以比一个更复杂的 Panel,比如 Grid,有明显的优势。
每当一个子控件改变其位置时,它都有可能触发布局系统的新一轮处理。因此,了解可以触发布局系统的事件非常重要,不必要的触发会导致应用程序的性能下降。以下是布局系统被调用时的过程描述。
- 一个子 - UIElement开始布局过程,首先测量其核心属性。
- 对 - Control上定义的大小属性进行评估,例如- Width、- Height和- Margin。
- 应用 - Panel特定的逻辑,例如- Dock方向或堆叠的- Orientation。
- 所有子元素测量完毕后,排列内容。 
- 在屏幕上绘制 - Children集合。
- 如果添加了额外的 - Children到集合中,则会再次调用该过程。
这个过程以及如何调用它将在下面的章节中详细介绍。
测量和排列子元素
布局系统为Children集合的每个成员完成两次遍历,分别为测量遍历和排列遍历。每个子Panel提供其自己的MeasureOverride和ArrangeOverride方法来实现其自己特定的布局行为。
在测量遍历期间,对Children集合的每个成员进行评估。该过程始于对Measure方法的调用。该方法在父Panel元素的实现中被调用,无需显式调用即可进行布局。
首先,会评估Visual的本机大小属性,例如Clip和IsVisible。这会生成一个约束,该约束传递给MeasureCore。
然后,处理影响约束值的框架属性。这些属性通常描述底层Control的大小特性,例如其Height、Width和Margin。每个这些属性都可以更改显示元素所需的空间。然后,将约束作为参数调用MeasureOverride。
由于Bounds是一个计算出来的值,因此您应该意识到,由于布局系统的各种操作,可能会有多个或递增的报告更改。布局系统可能正在为子元素计算所需的度量空间,由父元素约束等。
测量遍历的最终目标是让子元素确定其DesiredSize,这是在MeasureCore调用期间发生的。DesiredSize值由Measure存储,供内容排列遍历使用。
排列遍历始于对Arrange方法的调用。在排列遍历期间,父Panel元素生成代表子元素边界的矩形。该值传递给ArrangeCore方法进行处理。
ArrangeCore方法评估子元素的DesiredSize,并评估任何可能影响元素呈现大小的附加边距。ArrangeCore生成一个排列大小,将其作为参数传递给Panel的ArrangeOverride方法。ArrangeOverride生成子元素的finalSize。最后,ArrangeCore方法对偏移属性(如边距和对齐方式)进行最终评估,并将子元素放置在其布局插槽内。子元素不必(并且通常不会)填充整个分配的空间。然后将控制权返回到父Panel,布局过程完成。
本节内容
Last updated