Поделиться через


Панели макета

Панели макета — это контейнеры, которые позволяют упорядочивать и группировать элементы пользовательского интерфейса в приложении. Встроенные панели макета XAML включают RelativePanel, StackPanel, Grid, VariableSizedWrapGrid и Canvas. Здесь мы описываем каждую панель и покажем, как использовать ее для макета элементов пользовательского интерфейса XAML.

При выборе панели макета следует учитывать несколько факторов.

  • Как панель располагает свои дочерние элементы.
  • Как панель размерирует дочерние элементы.
  • Как перекрывающиеся дочерние элементы сложены поверх друг друга (z-order).
  • Количество и сложность элементов вложенной панели, необходимых для создания требуемого макета.

Примеры

Приложение Галерея WinUI 3 включает интерактивные примеры большинства элементов управления, особенностей и возможностей WinUI 3. Получение приложения из Microsoft Store или получение исходного кода на GitHub

Свойства панели

Прежде чем обсудить отдельные панели, давайте рассмотрим некоторые общие свойства, имеющиеся на всех панелях.

Присоединенные к панели свойства

Большинство панелей макета XAML используют присоединенные свойства, чтобы их дочерние элементы сообщали родительской панели о том, как они должны размещаться в пользовательском интерфейсе. Присоединенные свойства используют синтаксис AttachedPropertyProvider.PropertyName. Если у вас есть панели, вложенные в другие панели, атрибуты привязки на элементах UI, устанавливающие параметры макета для родительской панели, интерпретируются только ближайшей родительской панелью.

Ниже приведен пример настройки присоединенного свойства Canvas.Left в элементе управления Button в XAML. Это сообщает родительскому холсту, что кнопку следует разместить на 50 эффективных пикселей от левого края холста.

<Canvas>
  <Button Canvas.Left="50">Hello</Button>
</Canvas>

Дополнительные сведения о присоединённых свойствах см. в Обзор присоединённых свойств.

Границы панели

Панели RelativePanel, StackPanel и Grid определяют свойства границы, которые позволяют создать границу вокруг панели без дополнительного обрамления элементов в Border. Свойства границы: BorderBrush, BorderThickness, CornerRadius и Padding.

Ниже приведен пример задания свойств границы в сетке.

<Grid BorderBrush="Blue" BorderThickness="12" CornerRadius="12" Padding="12">
    <TextBlock Text="Hello World!"/>
</Grid>

Сетка с границами

Благодаря встроенным свойствам границы уменьшается число элементов XAML, что может повысить производительность пользовательского интерфейса приложения. Дополнительные сведения о панелях макета и производительности пользовательского интерфейса см. в статье "Оптимизация макета XAML".

RelativePanel

RelativePanel позволяет макетировать элементы пользовательского интерфейса, указывая, где они располагаются относительно других элементов и по отношению к самой панели. По умолчанию элемент размещается в левом верхнем углу панели. Вы можете использовать RelativePanel с VisualStateManager и AdaptiveTrigger для изменения пользовательского интерфейса для различных размеров окна.

В этой таблице показаны присоединенные свойства, которые можно использовать для выравнивания элемента относительно панели или других элементов.

Выравнивание панели Выравнивание с одноуровневыми элементами Расположение на одном уровне
AlignTopWithPanel AlignTopWith Над
AlignBottomWithPanel AlignBottomWith Ниже
AlignLeftWithPanel AlignLeftWith LeftOf
AlignRightWithPanel AlignRightWith RightOf
AlignHorizontalCenterWithPanel AlignHorizontalCenterWith  
AlignVerticalCenterWithPanel AlignVerticalCenterWith  

В этом XAML показано, как упорядочивать элементы в RelativePanel.

<RelativePanel BorderBrush="Gray" BorderThickness="1">
    <Rectangle x:Name="RedRect" Fill="Red" Height="44" Width="44"/>
    <Rectangle x:Name="BlueRect" Fill="Blue"
               Height="44" Width="88"
               RelativePanel.RightOf="RedRect" />

    <Rectangle x:Name="GreenRect" Fill="Green" 
               Height="44"
               RelativePanel.Below="RedRect" 
               RelativePanel.AlignLeftWith="RedRect" 
               RelativePanel.AlignRightWith="BlueRect"/>
    <Rectangle Fill="Orange"
               RelativePanel.Below="GreenRect" 
               RelativePanel.AlignLeftWith="BlueRect" 
               RelativePanel.AlignRightWithPanel="True"
               RelativePanel.AlignBottomWithPanel="True"/>
</RelativePanel>

Результат выглядит следующим образом.

Относительная панель

Ниже приведены некоторые сведения о размерах прямоугольников:

  • Красный прямоугольник имеет явный размер 44x44. Он помещается в левый верхний угол панели, которая является позицией по умолчанию.
  • Зеленый прямоугольник имеет явную высоту 44. Левая сторона выровнена с красным прямоугольником, а ее правая сторона выровнена с синей прямоугольникой, которая определяет ее ширину.
  • Оранжевому прямоугольнику не назначен явный размер. Левая сторона совпадает с голубым прямоугольником. Его правые и нижние края выровнены с краем панели. Его размер определяется этими выравниваниями и изменяется вместе с изменением размера панели.

StackPanel

StackPanel упорядочивает дочерние элементы в одну строку, которая может быть ориентирована горизонтально или вертикально. StackPanel обычно используется для упорядочивания небольшого подраздела пользовательского интерфейса на странице.

Свойство Orientation можно использовать для указания направления дочерних элементов. Ориентация по умолчанию — вертикальная.

В следующем XAML показано, как создать вертикальный StackPanel элементов.

<StackPanel>
    <Rectangle Fill="Red" Height="44"/>
    <Rectangle Fill="Blue" Height="44"/>
    <Rectangle Fill="Green" Height="44"/>
    <Rectangle Fill="Orange" Height="44"/>
</StackPanel>

Результат выглядит следующим образом.

StackPanel

Если размер дочернего элемента не задан явным образом, он растягивается для заполнения доступной ширины (или высоты, если ориентация является горизонтальной). В этом примере ширина прямоугольников не задана. Прямоугольники расширяются, чтобы заполнить всю ширину StackPanel.

Grid

Панель "Сетка" поддерживает гибкие макеты и позволяет упорядочивать элементы управления в макетах с несколькими строками и несколькими столбцами. Строки и столбцы сетки указываются с помощью свойств RowDefinitions и ColumnDefinitions .

Чтобы разместить объекты в определенных ячейках Сетки, используйте присоединенные свойства Grid.Column и Grid.Row .

Чтобы содержимое простиралось на несколько строк и столбцов, используйте присоединенные свойства Grid.RowSpan и Grid.ColumnSpan.

В этом примере XAML показано, как создать сетку с двумя строками и двумя столбцами.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="44"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Rectangle Fill="Red" Width="44"/>
    <Rectangle Fill="Blue" Grid.Row="1"/>
    <Rectangle Fill="Green" Grid.Column="1"/>
    <Rectangle Fill="Orange" Grid.Row="1" Grid.Column="1"/>
</Grid>

Результат выглядит следующим образом.

Сетка

В этом примере измерение происходит следующим образом:

  • Вторая строка имеет явную высоту 44 эффективных пикселей. По умолчанию высота первой строки заполняет все оставшееся пространство.
  • Ширина первого столбца установлена на Auto, поэтому она будет такой ширины, какой требуется для дочерних элементов. В этом случае, чтобы разместить ширину красного прямоугольника, требуется 44 эффективных пикселя.
  • На прямоугольниках нет других ограничений размера, поэтому каждая из них растягивается, чтобы заполнить ячейку сетки.

Пространство можно распределить в столбце или строке с помощью автоматического или звездочного размера. Вы используете автоизменение размера, чтобы элементы пользовательского интерфейса могли изменять свои размеры для соответствия их содержимому или родительскому контейнеру. Вы также можете использовать автоматическую настройку размера для строк и столбцов сетки. Чтобы использовать автоматическое изменение размера, задайте для высоты и (или) ширины элементов пользовательского интерфейса значение Auto.

Для равномерного распределения доступного пространства между строками и столбцами сетки используется пропорциональное изменение размеров, также называемое звездной размерностью. В XAML значения звезд выражаются как * (или n* для взвешированного размера звезд). Например, чтобы указать, что один столбец в 5 раз шире второго столбца в макете с 2 столбцами, используйте "5*" и "*" для свойств Width в элементах ColumnDefinition.

Этот пример объединяет фиксированный, автоматический и пропорциональный размер в сетке с 4 столбцами.

колонна Размеры Description
Колонка_1 Автоматически Размер столбца будет соответствовать его содержимому.
Столбец_2 * После вычисления автоматических столбцов столбец получает часть оставшейся ширины. Column_2 будет вполовину уже, чем Column_4.
Столбец_3 44 Столбец будет иметь ширину в 44 пикселях.
Column_4 2* После вычисления автоматических столбцов столбец получает часть оставшейся ширины. Column_4 будет в два раза больше, чем Column_2.

Ширина столбца по умолчанию — "*", поэтому не нужно явно задавать это значение для второго столбца.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
        <ColumnDefinition Width="44"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Column 1 sizes to its content." FontSize="24"/>
</Grid>

В конструкторе XAML Visual Studio результат выглядит следующим образом.

Сетка столбцов 4 в конструкторе Visual Studio

VariableSizedWrapGrid

VariableSizedWrapGrid — это панель макета в стиле сетки, в которой строки или столбцы автоматически упаковываются в новую строку или столбец при достижении значения MaximumRowsOrColumns .

Свойство Orientation указывает, добавляются ли элементы сетки в строки или столбцы перед переносом. Ориентация по умолчанию — "Вертикальная", что означает, что сетка добавляет элементы сверху вниз, пока столбец не будет заполнен, а затем переносится в новый столбец. Если значение равно горизонтально, сетка добавляет элементы слева направо, а затем помещается в новую строку.

Измерения ячеек задаются элементом ItemHeight и ItemWidth. Каждая ячейка имеет одинаковый размер. Если не указаны ItemHeight или ItemWidth, тогда первая ячейка подстраивается под содержимое, а остальные ячейки принимают размер первой ячейки.

Вы можете использовать присоединенные свойства VariableSizedWrapGrid.ColumnSpan и VariableSizedWrapGrid.RowSpan , чтобы указать, сколько смежных ячеек нужно заполнить дочерним элементом.

Вот как использовать VariableSizedWrapGrid в XAML.

<VariableSizedWrapGrid MaximumRowsOrColumns="3" ItemHeight="44" ItemWidth="44">
    <Rectangle Fill="Red"/>
    <Rectangle Fill="Blue" 
               VariableSizedWrapGrid.RowSpan="2"/>
    <Rectangle Fill="Green" 
               VariableSizedWrapGrid.ColumnSpan="2"/>
    <Rectangle Fill="Orange" 
               VariableSizedWrapGrid.RowSpan="2" 
               VariableSizedWrapGrid.ColumnSpan="2"/>
</VariableSizedWrapGrid>

Результат выглядит следующим образом.

Сетка с переменным размером

В этом примере максимальное число строк в каждом столбце равно 3. Первый столбец содержит только 2 элемента (красные и синие прямоугольники), так как синий прямоугольник охватывает 2 строки. Затем зеленый прямоугольник помещает в верхнюю часть следующего столбца.

Холст

Панель Canvas размещает дочерние элементы по фиксированным координатам и не поддерживает гибкие макеты. Вы указываете точки на отдельных дочерних элементах, задавая для каждого элемента присоединённые свойства Canvas.Left и Canvas.Top. Родительский холст считывает эти присоединённые значения свойств из дочерних элементов в ходе Arrange прохода расстановки.

Объекты на холсте могут перекрываться, где один объект рисуется поверх другого объекта. По умолчанию Холст отрисовывает дочерние объекты в том порядке, в котором они объявлены, поэтому последний дочерний элемент отображается сверху (каждый элемент имеет z-индекс по умолчанию 0). Это то же самое, что и другие встроенные панели. Однако Canvas также поддерживает присоединенное свойство Canvas.ZIndex , которое можно задать для каждого дочернего элемента. Это свойство можно задать в коде, чтобы изменить порядок рисования элементов во время выполнения. Элемент с наивысшим значением Canvas.ZIndex отрисовывается последним и, следовательно, отображается поверх всех других элементов, которые делят с ним одно и то же пространство или каким-либо образом перекрываются. Обратите внимание, что альфа-значение (прозрачность) учитывается, поэтому, даже если элементы перекрываются, содержимое, отображаемое в перекрывающихся областях, может быть смешано, если верхний элемент имеет не максимальное значение альфа.

Холст не изменяет размер своих дочерних элементов. Каждый элемент должен указать свой размер.

Ниже приведен пример холста в XAML.

<Canvas Width="120" Height="120">
    <Rectangle Fill="Red" Height="44" Width="44"/>
    <Rectangle Fill="Blue" Height="44" Width="44" Canvas.Left="20" Canvas.Top="20"/>
    <Rectangle Fill="Green" Height="44" Width="44" Canvas.Left="40" Canvas.Top="40"/>
    <Rectangle Fill="Orange" Height="44" Width="44" Canvas.Left="60" Canvas.Top="60"/>
</Canvas>

Результат выглядит следующим образом.

Canvas

Используйте панель Canvas по усмотрению. Хотя удобно точно управлять позициями элементов в пользовательском интерфейсе для некоторых сценариев, фиксированная позиционированная панель макета приводит к тому, что область пользовательского интерфейса будет менее адаптивной к общему размеру окна приложения. Изменение размера окна приложения может поступать из изменений ориентации устройства, разделения окон приложений, изменения мониторов и ряда других сценариев пользователя.

Панели для ItemsControl

Существует несколько панелей специального назначения, которые можно использовать только в качестве ItemsPanel для отображения элементов в ItemsControl. Это ItemsStackPanel, ItemsWrapGrid, VirtualizingStackPanel и WrapGrid. Эти панели нельзя использовать для общего макета пользовательского интерфейса.

Получите пример кода

  • Пример коллекции WinUI. Просмотрите все элементы управления XAML в интерактивном формате.