Построение графического интерфейса в Universal Windows Platform базируется на концепции компоновки. Компоновка (layout) представляет процесс позиционирования элементов внутри контейнера. Благодаря компоновке мы можем уйти от жестко закодированных размеров элементов в сторону "резинового" дизайна и адаптивных интерфейсов, которые проще подстроить под различные разрешения экранов.
В Universal Windows Platform компоновка выполняется с помощью специальных контейнеров. В частности, нам доступны следующие контейнеры компоновки: Grid, VariableSizedWrapGrid, StackPanel, SplitView, RelativePanel и Canvas. Контейнеры компоновки позволяют эффективно распределить доступное пространство между элементами, найти для него наиболее предпочтительные размеры. Также они могут содержать внутри себя другие контейнеры, например, StackPanel в Grid. Поэтому, чтобы добиться нужного нам эффекта в размещении элементов, мы можем помещать однни контейнеры в другие, комбинировать их. Кроме того, если нам не хватает стандартных контейнеров, мы можем определить свои с нужной нам функциональностью.
Все выше перечисленные контейнеры компоновки наследуются от класса Panel, которое предоставляет ряд базовых свойств и методов. А само дерево наследования можно представить следующим образом:
В частности, отличительной чертой контейнеров компоновки является свойство Children, которое включает все вложенные контейнер элементы. Например, возьмем стандартный контейнер Grid:
<Grid x:Name="layoutGrid"> <Button Content="Hello" /> </Grid>
Здесь в грид помещена кнопка. Этот код эквивалентен следующему:
<Grid x:Name="layoutGrid"> <Grid.Children> <Button Content="Hello" /> </Grid.Children> </Grid>
Свойство Children представляет коллекцию UIElementCollection
, которая содержит объекты UIElement. Практически все стандартные элементы в Universal
Windows Platform представляют тип UIElement. И как многие стандартные коллекции, коллекция Children имеет методы для управления содержимым:
Add(UIElement item)
: добавляет UIElement в контейнер
Remove(UIElement item)
: удаляет UIElement из контейнера
RemoveAt(int index)
: удаляет элемент из контейнера по индексу в коллекции Children
Move(int oldIndex, int newIndex)
: перемещает элемент в коллекции с одного индекса на другой
Clear()
: удаляет все элементы из коллекции
Например, в коде C# мы могли бы изменять содержимое контейнера компоновки:
Button button1 = new Button { Content = "Button 1", VerticalAlignment=VerticalAlignment.Top }; layoutGrid.Children.Add(button1); // добавляем кнопку layoutGrid.Children.Remove(button1); // удаляем кнопку layoutGrid.Children.Clear(); // удаляем все элементы
Хотя в данном случае мы рассматривали работу с элементами для контейнера Grid, но все то же самое будет характерно и для других контейнеров компоновки.
Процесс компоновки проходит два этапа: измерение (measure) и расстановка (arrange). На этапе измерения контейнер производит измерение предпочтительного для дочерних элементов места. Однако не всегда контейнер имеет достаточно места, чтобы расставить все элементы в соответствии с их предпочтительными размерами, поэтому их размеры приходится усекать. Затем происходит этап непосредственной расстановки дочерних элементов внутри контейнера.
Теперь рассмотрим подробнее отдельные контейнеры компоновки.