Контейнеры компоновки (макеты) используются для того, чтобы упорядочить различные элементы управления на странице приложения или на в отдельное её части. В .NET MAUI мы можем использовать различные контейнеры, позволяющие упорядочивать компоненты, располагая их по горизонтали, вертикали, в табличном виде и так далее. Так, можно выделить следующие контейнеры компоновки доступные нам в .NET MAUI: StackLayout, HorizontalStackLayout, VerticalStackLayout, AbsoluteLayout, FlexLayout и Grid. Разберемся с работой этих компонентов и начнем с первых трех — StackLayout, HorizontalStackLayout и VerticalStackLayout так как это, можно сказать, «родственные» компоненты.
StackLayout
Контейнер StackLayout предназначен для размещения компонентов в стеке, то есть упорядочивает их в каком-либо направлении — по горизонтали или вертикали. Для указания направления используется свойство Orientation, которое может принимать следующие значения:
| Имя | Значение | Описание |
|---|---|---|
Vertical |
0 |
Компоненты в контейнере упорядочиваются по вертикали сверху вниз. |
Horizontal |
1 |
Компоненты в контейнере упорядочиваются по горизонтали слева направо. |
Например, создадим новое приложение .NET MAUI и изменим код XAML страницы MainPage.xaml следующим образом:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp2.MainPage" >
<StackLayout Orientation="Vertical">
<Label Text="Первая метка"/>
<Label Text="Вторая метка"/>
<Label Text="Третья метка"/>
<Label Text="Четвертая метка"/>
</StackLayout>
</ContentPage>
В итоге, все метки будут расположены по вертикали сверху вниз следующим образом:
Если же выстроить все элементы в StackLayout по горизонтали, то есть вот так:
<StackLayout Orientation="Horizontal">
<Label Text="Первая метка"/>
<Label Text="Вторая метка"/>
<Label Text="Третья метка"/>
<Label Text="Четвертая метка"/>
</StackLayout>
то при значении всех прочих свойств контейнера по умолчанию мы получим вот такой вид страницы нашего приложения:
Как видите, наши метки вплотную прижимаются друг к другу. Чтобы между компонентами в контейнере было какое-то расстояние, мы могли бы воспользоваться уже известными нам свойствами позиционирования элементов и настроить внешний отступ каждой метки, а можем воспользоваться свойством Spacing самого контейнера, которое задает размер пространства между дочерними элементами контейнера, например, вот так:
<StackLayout Orientation="Horizontal" Spacing="10">
<Label Text="Первая метка"/>
<Label Text="Вторая метка"/>
<Label Text="Третья метка"/>
<Label Text="Четвертая метка"/>
</StackLayout>
В итоге мы получим следующий вид:
При необходимости, мы можем менять положение и размер каждого дочернего элемента контейнера StackLayout, используя его свойства. Например,
<StackLayout Orientation="Vertical" Spacing="10">
<Button Text="Первая кнопка" WidthRequest="120" HorizontalOptions="Center"/>
<Button Text="Вторая кнопка" WidthRequest="200" HeightRequest="100" HorizontalOptions="End"/>
<Button Text="Третья кнопка" HeightRequest="60" WidthRequest="100" HorizontalOptions="Start"/>
</StackLayout>
Здесь мы располагаем все элементы в контейнере по вертикали, то есть, условно, каждый компонент занимает одну «строку» в стеке. При этом, мы меняем размер и положение каждой кнопки в строке. используя их собственные свойства WidthRequest, HeightRequest и HorizontalOptions. В результате, кнопки расположатся в контейнере следующим образом: 
И, само собой разумеется, так как StackLayout представляет собой контейнер для других элементов, то никто нам не запретит вложить один контейнер в другой, например так:
<StackLayout Orientation="Vertical" Spacing="10" Background="Green">
<StackLayout Orientation="Vertical" Background="MediumVioletRed">
<Button Text="Первая кнопка" WidthRequest="120" HorizontalOptions="Center"/>
<Button Text="Вторая кнопка" WidthRequest="200" HeightRequest="100" HorizontalOptions="End"/>
<Button Text="Третья кнопка" HeightRequest="60" WidthRequest="100" HorizontalOptions="Start"/>
</StackLayout>
<StackLayout Orientation="Horizontal" Spacing="10" Background="Blue">
<Label Text="Первая метка"/>
<Label Text="Вторая метка"/>
<Label Text="Третья метка"/>
</StackLayout>
</StackLayout>
Здесь для наглядности каждый контейнер имеет свой цвет: внешний контейнер — зеленого цвета и два внутренних: первый с расположением компонентов по вертикали — красный, второй с расположением компонентов по горизонтали — синий. В результате мы получим следующий внешний вид страницы:
Однако, стоит отметить, что делать такие вложения одного контейнера в другой стоит с осторожностью, так как в этом случае платформе требуется проводить дополнительные вычисления для построения всего макета приложения, что может привести к потере производительности приложения.
HorizontalStackLayout и VerticalStackLayout
Эти два компонента, по сути, аналогичны StackLayout, однако предназначены для расположения компонентов только в одном направлении — либо по горизонтали (HorizontalStackLayout), либо по вертикали (VerticalStackLayout). То есть предыдущий пример с вложенными контейнерами мы могли бы переписать следующим образом, не меняя внешний вид приложения:
<VerticalStackLayout Spacing="10" Background="Green">
<VerticalStackLayout Background="MediumVioletRed">
<Button Text="Первая кнопка" WidthRequest="120" HorizontalOptions="Center"/>
<Button Text="Вторая кнопка" WidthRequest="200" HeightRequest="100" HorizontalOptions="End"/>
<Button Text="Третья кнопка" HeightRequest="60" WidthRequest="100" HorizontalOptions="Start"/>
</VerticalStackLayout>
<HorizontalStackLayout Spacing="10" Background="Blue">
<Label Text="Первая метка"/>
<Label Text="Вторая метка"/>
<Label Text="Третья метка"/>
</HorizontalStackLayout>
</VerticalStackLayout>
Итого
Для компоновки элементов управления на странице приложения мы можем использовать различные контейнеры (макеты). Компонент-контейнер StackLayout позволяет упорядочивать компоненты по горизонтали и вертикали. В свою очередь, HorizontalStackLayout упорядочивает компоненты только по горизонтали, а VerticalStackLayout — только по вертикали.
