Контейнер Grid — это еще один контейнер компоновки, доступный нам в .NET MAUI. Отличие от рассмотренных нами ранее контейнеров компоновки, Grid
позволяет размещать дочерние компоненты в сетке (таблице). В этой части мы рассмотрим основные моменты по использованию Grid
в XAML.
Стоит отметить, что Grid в .NET MAUI — это именно контейнер компоновки и его не следует путать с обычно таблицей, например, наподобие таблиц в HTML.
Работа со строками и столбцами Grid
По умолчанию, Grid
уже содержит оду строку и один столбец. Поэтому, если нам достаточно всего одной ячейки сетки, то можно создать вот такой код XAML:
<Grid> <Button Text="Item 1" Background="Red"></Button> </Grid>
При этом, опять же, по умолчанию, кнопка растянется на всё доступное пространство в контейнере:Следует также обратить внимание на то, что каждый следующий дочерний элемент
Grid
также будет растягиваться на всё пространство и размещаться поверх предыдущего элемента. То есть вот такой код:
<Grid> <Button Text="Item 1" Background="Red"></Button> <Button Text="Item 2" Background="Aqua"></Button> <Button Text="Item 3" Background="Green"></Button> <Button Text="Item 4" Background="DarkOrange"></Button> </Grid>
приведет к тому, что последний элемент закроет все предыдущие. То есть мы увидим вот такую страницу приложения:Чтобы определить строки и столбцы в Grid, мы должны использовать свойства компонента:
RowDefinition
— для определения каждой новой строки сеткиColumnDefinition
— для определения каждого нового столбца сетки
Например, определим в нашей таблице 4 строки и 4 столбца:
<Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> </Grid>
Здесь Grid.RowDefinitions
— коллекция строк, а Grid.ColumnDefinitions
— коллекция столбцов. Теперь мы можем размещать в каждой ячейке сетки какие-либо элементы управления. Делается это с помощью присоединенных свойств, которых мы узнали в предыдущей части, следующим образом:
<Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Button Text="Item 1" Background="Red" Grid.Row="0" Grid.Column="0"></Button> <Button Text="Item 2" Background="Aqua" Grid.Row="1" Grid.Column="1"></Button> <Button Text="Item 3" Background="Green" Grid.Row="2" Grid.Column="2"></Button> <Button Text="Item 4" Background="DarkOrange" Grid.Row="3" Grid.Column="3"></Button> </Grid>
Здесь присоединенное свойство Grid.Row
определяет порядковый номер строки в которой будет расположен дочерний элемента, а Grid.Column
— порядковый номер столбца. По приведенному выше коду можно понять, что мы пытаемся разместить кнопки по диагонали, то есть вот так:
Размеры строк и столбцов
В приведенном выше примере мы не указывали никаких размеров для строк и столбцов сетки, поэтому размеры ячеек получились одинаковыми. Такое поведение макета не всегда удобно — бывает необходимо установить, например, столбцу в центре автоматический размер, а столбцам слева и справа — фиксированный. При установлении размеров строк и столбцов Grid
следует учитывать, что:
RowDefinition
(строка) может содержать размер высоты (Height
)ColumnDefinition
(столбец) — может содержать только ширину (Width
)
Как и в случае с размерами в AbsoluteLayout
, мы можем указывать размеры как в абсолютных величинах, так и в единицах пропорции. Абсолютные размеры можно указывать обычным образом, например:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="100"></RowDefinition> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="90"></RowDefinition> <RowDefinition Height="200"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="140"></ColumnDefinition> <ColumnDefinition Width="150"></ColumnDefinition> <ColumnDefinition Width="160"></ColumnDefinition> <ColumnDefinition Width="170"></ColumnDefinition> </Grid.ColumnDefinitions> <Button Text="Item 1" Background="Red" Grid.Row="0" Grid.Column="0"></Button> <Button Text="Item 2" Background="Aqua" Grid.Row="1" Grid.Column="1"></Button> <Button Text="Item 3" Background="Green" Grid.Row="2" Grid.Column="2"></Button> <Button Text="Item 4" Background="DarkOrange" Grid.Row="3" Grid.Column="3"></Button> </Grid>
Здесь мы задали абсолютные значения для ширины столбцов и высоты строк, поэтому на экране мы увидим вот такой неприглядный внешний вид:Что касается пропорциональных размеров, то здесь все обстоит немного сложнее. Рассмотрим вот такой пример:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="1*"></RowDefinition> <RowDefinition Height="4*"></RowDefinition> <RowDefinition Height="1*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"></ColumnDefinition> <ColumnDefinition Width="4*"></ColumnDefinition> <ColumnDefinition Width="1*"></ColumnDefinition> </Grid.ColumnDefinitions> <Button Text="Item 1" Background="Red" Grid.Row="0" Grid.Column="0"></Button> <Button Text="Item 2" Background="Aqua" Grid.Row="1" Grid.Column="1"></Button> <Button Text="Item 3" Background="Green" Grid.Row="2" Grid.Column="2"></Button> </Grid>
Обратите внимание на то, как определены значения размеров — в конце числа стоит символ «звездочка» — *
. Этот символ указывает на то, что размер рассчитывается пропорционально. При этом расчёт ведется следующим образом (на примере высот):
- 1 + 4 + 1 = 6 — суммарный размер высот всех строк.
- 1/6 — высота первой строки
- 4/6 (или 2/3) — высота второй строки
- 1/6 — высота третьей строки
Аналогичным образом рассчитывается и ширина столбцов. В итоге, внешний вид нашей сетки с кнопками будет вот таким: При необходимости, мы можем комбинировать пропорциональные и абсолютные размеры.
Отступы в ячейках сетки
Чтобы сделать отступы в строках и столбцах Grid, используются свойства ColumnSpacing
и RowSpacing
контейнера Grid
. Например,
<Grid RowSpacing="10" ColumnSpacing="10"> <Grid.RowDefinitions> <RowDefinition Height="1*"></RowDefinition> <RowDefinition Height="1*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"></ColumnDefinition> <ColumnDefinition Width="1*"></ColumnDefinition> </Grid.ColumnDefinitions> <BoxView Background="Red" Grid.Row="0" Grid.Column="0"></BoxView> <BoxView Background="Aqua" Grid.Row="0" Grid.Column="1"></BoxView> <BoxView Background="Green" Grid.Row="1" Grid.Column="1"></BoxView> <BoxView Background="Yellow" Grid.Row="1" Grid.Column="0"></BoxView> </Grid>
В результате получим вот такой внешний вид приложения: Объединение строк и столбцов
Чтобы объединить несколько строк, используется присоединенное свойство Grid.RowSpan
, а для объединения столбцов — Grid.ColumnSpan
. Например, объединим два столбца в сетке, которая показана на рисунке выше
<Grid RowSpacing="10" ColumnSpacing="10"> <Grid.RowDefinitions> <RowDefinition Height="1*"></RowDefinition> <RowDefinition Height="1*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"></ColumnDefinition> <ColumnDefinition Width="1*"></ColumnDefinition> </Grid.ColumnDefinitions> <BoxView Background="Red" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"></BoxView> <BoxView Background="Green" Grid.Row="1" Grid.Column="1"></BoxView> <BoxView Background="Yellow" Grid.Row="1" Grid.Column="0"></BoxView> </Grid>
Итого
Контейнер компоновки Grid
используется для размещения содержимого в виде сетки. Размеры ячеек сетки могут задаваться как в абсолютных величинах, так и пропорционально. При необходимости, мы можем объединять строки и столбцы сетки, используя присоединенные свойства.