Компоновка
Компоновка решает, где находится каждый элемент и какого он размера. В каждом кадре, где что-то изменилось, IcyUI спрашивает каждый элемент, какого размера он хочет быть, а затем выдаёт ему прямоугольник для заполнения. Панели решают, как дочерние элементы делят их место; размер, отступы и выравнивание каждого дочернего элемента решают, где он окажется в доставшейся ему части.
Сначала измерение, потом размещение
Компоновка выполняется в два прохода, от Canvas вниз:
- Измерение (measure): каждый элемент сообщает желаемый размер, исходя из своего содержимого (текста, изображения, дочерних элементов) и собственных свойств размера.
- Размещение (arrange): каждый родитель выдаёт каждому дочернему элементу прямоугольник. Дочерний элемент располагается в нём согласно своим отступам и выравниванию и размещает собственных потомков.
Изменение свойства, влияющего на размер (текста, размера шрифта, отступов, дочерних элементов), помечает элемент для нового измерения; в следующем кадре он компонуется заново. Вызывать компоновку самостоятельно не нужно.
Размер
| Свойство | Значение |
|---|---|
| Width / Height | Фиксированный размер. По умолчанию не задан (NaN), что означает «по содержимому или по выданному месту». |
| MinWidth / MaxWidth (и высоты) | Пределы итогового размера элемента. |
| Margin | Внешний отступ: место снаружи элемента, между ним и соседями или родителем. |
| Padding | Внутренний отступ: место внутри элемента, между его рамкой и содержимым. |
Thickness записывается в целых единицах: "8" (все стороны), "8,4" (слева/справа, сверху/снизу) или
"8,4,8,0" (слева, сверху, справа, снизу).
Выравнивание
Внутри выданного прямоугольника элемент располагается согласно HorizontalAlignment (Left,
Center, Right, Stretch) и VerticalAlignment (Top, Center, Bottom, Stretch).
Stretch заполняет прямоугольник, если не задан Width/Height; остальные значения подгоняют размер под содержимое.
<!-- Each child gets the space its parent offers; its size, margin and alignment decide where it sits in it. -->
<StackPanel Orientation="Vertical" Width="320" Padding="8">
<Button HorizontalAlignment="Left" Margin="0,0,0,8">Left</Button>
<Button Margin="0,0,0,8">Centered (the theme's default for buttons)</Button>
<Button HorizontalAlignment="Stretch" Margin="0,0,0,8">Stretch</Button>
<Button HorizontalAlignment="Right" MinWidth="160">Right, at least 160 wide</Button>
</StackPanel>
По умолчанию элементы растягиваются. Тема по умолчанию центрирует кнопки, чтобы кнопка, добавленная прямо на Canvas, не
закрывала игру; локальный HorizontalAlignment="Stretch" у кнопки снова заставляет её заполнить свою ячейку.
Панели
| Панель | Как делит своё место |
|---|---|
StackPanel |
Дочерние элементы друг за другом, в столбец или в строку. |
Grid |
Строки и столбцы размера Auto, в пикселях или долями (*, 2*); дочерние элементы занимают ячейки. |
WrapGrid |
Одинаковые ячейки в строках с переносом, для инвентаря. |
ScrollViewer |
Содержимое больше самой панели, с прокруткой. |
SplitPane |
Две части с перетаскиваемым разделителем. |
Свойства каждой панели описаны на страницах Панели и Прокрутка.
Список (ListBox или WrapGrid) вне ScrollViewer подстраивает размер под свои элементы.
Масштаб
Компоновка работает в единицах интерфейса. При отрисовке Canvas умножает их на свой масштаб (DPI дисплея или опорное разрешение), поэтому панель шириной 200 единиц сохраняет физический размер и на 4K-экране. См. DPI и масштабирование.
Типичные ошибки
- Незаданные пределы равны
NaN. В собственных элементах управления не передавайтеWidthилиMinWidthпрямо вMath.Min,Math.Maxилиfloat.Clamp: границаNaNдаётNaN. Сначала проверьтеfloat.IsNaN. - Растянутому элементу в родителе, подстраивающемся под содержимое, некуда растягиваться. В строке
StackPanelStretchвдоль строки означает «по содержимому»; задайте элементуWidthили используйтеGridсо столбцом*. - Скрытые элементы сохраняют своё место. См. Canvas, хост и дерево элементов.