Перейти к основному содержимому

Обзор панелей

Элементы Panel - это компоненты, которые управляют отрисовкой элементов - их размером и габаритами, их позицией и расположением их дочернего содержимого. Avalonia UI предоставляет ряд предопределенных элементов Panel, а также возможность создавать пользовательские элементы Panel.

Класс Panel

Panel является базовым классом для всех элементов, обеспечивающих поддержку макета в Avalonia. Производные элементы Panel используются для позиционирования и размещения элементов в XAML и коде.

Avalonia включает комплексный набор производных реализаций панелей, которые позволяют создавать множество сложных макетов. Эти производные классы предоставляют свойства и методы, обеспечивающие реализацию большинства стандартных сценариев пользовательского интерфейса. Разработчики, не сумевшие найти поведение размещения дочерних элементов, соответствующее их потребностям, могут создавать новые макеты, переопределяя методы ArrangeOverride и MeasureOverride. Для получения дополнительной информации о пользовательском поведении макета см. Создание пользовательской панели.

Общие члены Panel

Все элементы Panel поддерживают базовые свойства размера и позиционирования, определенные Control, включая Height, Width, HorizontalAlignment, VerticalAlignment и Margin. Для получения дополнительной информации о свойствах позиционирования, определенных Control, см. Обзор выравнивания, полей и отступов.

Panel предоставляет дополнительные свойства, имеющие решающее значение для понимания и использования макета. Свойство Background используется для заполнения области между границами производного элемента панели с помощью Brush. Children представляет коллекцию дочерних элементов, из которых состоит Panel.

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

Производные элементы панели широко используют присоединенные свойства. Присоединенное свойство — это специализированная форма свойства зависимости, которая не имеет обычной «обертки» свойства CLR (common language runtime). Присоединенные свойства имеют специализированный синтаксис в XAML, который можно увидеть в нескольких примерах ниже.

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

Панели пользовательского интерфейса

В Avalonia доступно несколько классов панелей, оптимизированных для поддержки сценариев пользовательского интерфейса: Panel, Canvas, DockPanel, Grid, StackPanel, WrapPanel и RelativePanel. Эти элементы панели просты в использовании, универсальны и достаточно расширяемы для большинства приложений.

Canvas

Элемент Canvas позволяет позиционировать содержимое в соответствии с абсолютными координатами x и y. Элементы могут быть отрисованы в уникальном местоположении; или, если элементы занимают одни и те же координаты, порядок, в котором они появляются в разметке, определяет порядок, в котором элементы отрисовываются.

Canvas обеспечивает наиболее гибкую поддержку макета среди всех Panel. Свойства Height и Width используются для определения области холста, а элементам внутри назначаются абсолютные координаты относительно области родительского Canvas. Четыре присоединенных свойства, Canvas.Left, Canvas.Top, Canvas.Right и Canvas.Bottom, обеспечивают точный контроль размещения объектов в пределах Canvas, позволяя разработчику точно позиционировать и располагать элементы на экране.

ClipToBounds в Canvas

Canvas может размещать дочерние элементы в любом положении на экране, даже в координатах, которые находятся за пределами его собственных определенных Height и Width. Кроме того, на Canvas не влияет размер его дочерних элементов. В результате дочерний элемент может перерисовать другие элементы за пределами ограничивающего прямоугольника родительского Canvas. По умолчанию Canvas позволяет дочерним элементам отрисовываться за пределами границ родительского Canvas. Если такое поведение нежелательно, свойство ClipToBounds можно установить в значение true. Это заставляет Canvas обрезать содержимое до своего собственного размера. Canvas — единственный элемент макета, который позволяет дочерним элементам отрисовываться за пределами своих границ.

Определение и использование Canvas

Canvas можно создать, просто используя XAML или код. Следующий пример демонстрирует, как использовать Canvas для абсолютного позиционирования содержимого. Этот код создает три квадрата размером 100 пикселей. Первый квадрат красный, и его верхняя левая позиция (x, y) указана как (0, 0). Второй квадрат зеленый, и его верхняя левая позиция — (100, 100), чуть ниже и правее первого квадрата. Третий квадрат синий, и его верхняя левая позиция — (50, 50), таким образом, он охватывает нижний правый квадрант первого квадрата и верхний левый квадрант второго. Поскольку третий квадрат размещается последним, он появляется поверх двух других квадратов, то есть перекрывающиеся части принимают цвет третьего квадрата.

StackPanel Example
<Canvas Height="400" Width="400">
<Canvas Height="100" Width="100" Top="0" Left="0" Background="Red"/>
<Canvas Height="100" Width="100" Top="100" Left="100" Background="Green"/>
<Canvas Height="100" Width="100" Top="50" Left="50" Background="Blue"/>
</Canvas>

DockPanel

Элемент DockPanel использует присоединенное свойство DockPanel.Dock, установленное в дочерних элементах содержимого, для позиционирования содержимого вдоль краев контейнера. Когда DockPanel.Dock установлен в Top или Bottom, он располагает дочерние элементы выше или ниже друг друга. Когда DockPanel.Dock установлен в Left или Right, он располагает дочерние элементы слева или справа друг от друга. Свойство LastChildFill определяет положение последнего элемента, добавленного в качестве дочернего элемента DockPanel.

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

Изменение размера по содержимому

Если свойства Height и Width не указаны, DockPanel изменяет размер в соответствии с содержимым. Размер может увеличиваться или уменьшаться в соответствии с размером его дочерних элементов. Однако, когда эти свойства указаны и больше нет места для следующего указанного дочернего элемента, DockPanel не отображает этот дочерний элемент или последующие дочерние элементы и не измеряет последующие дочерние элементы.

LastChildFill

По умолчанию последний дочерний элемент элемента DockPanel «заполняет» оставшееся, нераспределенное пространство. Если такое поведение нежелательно, установите свойство LastChildFill в значение false.

Определение и использование DockPanel

Следующий пример демонстрирует, как разделить пространство с помощью DockPanel. Пять элементов Border добавляются как дочерние элементы родительского DockPanel. Каждый использует различное свойство позиционирования DockPanel для разделения пространства. Последний элемент «заполняет» оставшееся, нераспределенное пространство.

StackPanel Example
<DockPanel LastChildFill="True">
<Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25" Background="LemonChiffon" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
<TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
</Border>
<Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
<TextBlock Foreground="Black">Dock = "Left"</TextBlock>
</Border>
<Border Background="White" BorderBrush="Black" BorderThickness="1">
<TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock>
</Border>
</DockPanel>

Grid

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

Поведение размеров столбцов и строк

Столбцы и строки, определенные в Grid, могут использовать преимущества размера Star для пропорционального распределения оставшегося пространства. Когда Star выбран в качестве высоты или ширины строки или столбца, этот столбец или строка получает взвешенную долю оставшегося доступного пространства. Это отличается от Auto, который будет распределять пространство равномерно в зависимости от размера содержимого в столбце или строке. Это значение выражается как * или 2* при использовании XAML. В первом случае строка или столбец получили бы пространство, равное доступному, во втором случае — в два раза больше и так далее. Комбинируя этот метод для пропорционального распределения пространства со значениями HorizontalAlignment и VerticalAlignment, равными Stretch, можно разделить пространство макета по процентам от экранного пространства. Grid — единственная панель макета, способная распределять пространство таким образом.

Определение и использование Grid

Следующий пример демонстрирует, как создать пользовательский интерфейс, похожий на диалоговое окно "Выполнить", доступное в меню "Пуск" Windows.

Grid Example App
<Grid Background="Gainsboro" 
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="425"
Height="165"
ColumnDefinitions="Auto,*,*,*,*"
RowDefinitions="Auto,Auto,*,Auto">

<Image Grid.Row="0" Grid.Column="0" Source="{Binding runicon}" />

<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="4"
Text="Type the name of a program, folder, document, or Internet resource, and Windows will open it for you."
TextWrapping="Wrap" />

<TextBlock Grid.Row="1" Grid.Column="0" Text="Open:" />

<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" />

<Button Grid.Row="3" Grid.Column="2" Content="OK" Margin="10,0,10,15" />

<Button Grid.Row="3" Grid.Column="3" Content="Cancel" Margin="10,0,10,15" />

<Button Grid.Row="3" Grid.Column="4" Content="Browse ..." Margin="10,0,10,15" />
</Grid>

StackPanel

Панель StackPanel позволяет «складывать» элементы в заданном направлении. Направление стека по умолчанию — вертикальное. Для управления потоком содержимого можно использовать свойство Orientation.

StackPanel в сравнении с DockPanel

Хотя DockPanel также может «складывать» дочерние элементы, DockPanel и StackPanel не дают аналогичных результатов в некоторых сценариях использования. Например, порядок дочерних элементов может влиять на их размер в DockPanel, но не в StackPanel. Это происходит потому, что StackPanel измеряет в направлении укладки как PositiveInfinity, тогда как DockPanel измеряет только доступный размер.

Определение и использование StackPanel

Следующий пример демонстрирует, как использовать StackPanel для создания набора вертикально расположенных кнопок. Для горизонтального расположения установите свойство Orientation в значение Horizontal.

StackPanel Example
 <StackPanel HorizontalAlignment="Center" 
VerticalAlignment="Top"
Spacing="25">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
</StackPanel>

WrapPanel

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

Следующий пример демонстрирует, как создать WrapPanel для отображения элементов управления Button, которые переносятся на новую строку при достижении края своего контейнера.

StackPanel Example
<Border HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="2">
<WrapPanel Background="LightBlue" Width="200" Height="100">
<Button Width="200">Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</WrapPanel>
</Border>

Вложенные элементы панели

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

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

UniformGrid

UniformGrid — это тип панели, обеспечивающий однородный макет сетки. Это означает, что он располагает свои дочерние элементы в сетке, где все ячейки в сетке имеют одинаковый размер. В отличие от стандартной Grid, UniformGrid не поддерживает явные строки и столбцы, а также не предоставляет присоединенные свойства Grid.Row или Grid.Column.

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

Свойства UniformGrid

  • Rows и Columns: UniformGrid использует свойства Rows и Columns для определения макета своих дочерних элементов. Если вы установите только одно из этих свойств, UniformGrid автоматически вычислит другое, чтобы создать сетку, соответствующую общему количеству дочерних элементов. Если вы не установите ни одно из свойств, UniformGrid по умолчанию будет использовать сетку 1x1.

Например, если у вас 12 элементов и вы установите Rows на 3, UniformGrid автоматически создаст 4 столбца. Если вы установите Columns на 4, он автоматически создаст 3 строки.

  • FirstColumn: Свойство FirstColumn позволяет оставить определенное количество ячеек пустыми в первой строке сетки.

Определение и использование UniformGrid

Следующий пример демонстрирует, как определить и использовать UniformGrid. Пример создает UniformGrid с 3 строками и 4 столбцами и добавляет 12 прямоугольников в качестве дочерних элементов.

StackPanel Example
<UniformGrid Rows="3" Columns="4">
<Rectangle Width="50" Height="50" Fill="#330000"/>
<Rectangle Width="50" Height="50" Fill="#660000"/>
<Rectangle Width="50" Height="50" Fill="#990000"/>
<Rectangle Width="50" Height="50" Fill="#CC0000"/>
<Rectangle Width="50" Height="50" Fill="#FF0000"/>
<Rectangle Width="50" Height="50" Fill="#FF3300"/>
<Rectangle Width="50" Height="50" Fill="#FF6600"/>
<Rectangle Width="50" Height="50" Fill="#FF9900"/>
<Rectangle Width="50" Height="50" Fill="#FFCC00"/>
<Rectangle Width="50" Height="50" Fill="#FFFF00"/>
<Rectangle Width="50" Height="50" Fill="#FFFF33"/>
<Rectangle Width="50" Height="50" Fill="#FFFF66"/>
</UniformGrid>

В приведенном выше примере каждый Rectangle автоматически назначается ячейке в сетке в том порядке, в котором они были добавлены.