Выравнивание

39

В предыдущих статьях было рассказано о выравнивании различных элементов управления в контейнере с помощью свойств HorizontalAlignment и VerticalAlignment, определенных в базовом классе FrameworkElement. Но когда в элементе уже есть содержимое, необходимо рассмотреть другой уровень организации: выравнивание этого содержимого внутри границ элемента управления. Для этого предназначены свойства HorizontalContentAlignment и VerticalContentAlignment.

Эти свойства могут принимать те же значения, что и свойства HorizontalAlignment и VerticalAlignment. Это означает, что содержимое можно выровнять по любой границе элемента: верхней (Тор), нижней (Bottom), левой (Left) или правой (Right)), разместить в центре (Center) или растянуть на все доступное место (Stretch). Эти параметры применяются непосредственно к вложенным элементам управления содержимым, но можно использовать несколько уровней вложения, чтобы создать компоновку произвольной сложности.

Например, при вложении StackPanel в элементе Label свойство Label.HorizontalContentAlignment определяет расположение StackPanel, но всю остальную компоновку определяют параметры выравнивания и размера элемента StackPanel и его дочерних элементов.

У элементов управления содержимым есть так же свойство — Padding (отступ), которое вставляет промежутки между границами элемента и границами его содержимого. Чтобы понять, в чем разница, сравните две следующие кнопки:

<Button Margin="3">Кнопка без отступов</Button>
<Button Padding="5" Margin="3">Padding = 5</Button>

В кнопке без отступов (по умолчанию) текст прижат к краям кнопки. А кнопка с отступом в 5 единиц с каждой стороны получается более просторной. Эта разница показана на рисунке:

Отступы WPF

Свойства HorizontalContentAlignment, VerticalContentAlignment и Padding определены в классе Control, а не в более конкретном классе ContentControl — т.к. могут быть элементы, не являющиеся элементами управления содержимым, но все-таки имеющие какое-то содержимое. Примером может служить TextBox: текст, который содержится в нем (в свойстве Text), оформляется с учетом применяемых к нему параметров выравнивания и отступа.

Философия содержимого в WPF

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

Рассмотрим пример, приводившийся в предыдущей статье — простую кнопку с рисунком, где элемент Image содержится в элементе Button. Это подход далеко не идеален, т.к. битовые изображения не являются независимыми от разрешения. На дисплее с высоким разрешением картинка будет размазанной, т.к. WPF придется добавлять в нее с помощью интерполяции дополнительные пиксели, чтобы выдержать необходимый размер. Более сложные интерфейсы WPF используют для создания пользовательских кнопок не битовые изображения, а комбинации векторных фигур и другие графические фишки.

Этот подход замечательно гармонирует с моделью управления содержимым. Поскольку класс Button является элементом управления содержимым, у вас есть возможность заполнить его не только битовым, но и другим содержимым. Например, можно воспользоваться классами из пространства имен System.Windows.Shapes и рисовать на кнопках всякие векторные картинки. Следующий пример создает кнопку с двумя вытянутыми ромбами:

<Button Margin="5">
            <Grid>
                <Polygon Points="100,25 125,0 200,25 125,50" Fill="LightSteelBlue"></Polygon>
                <Polygon Points="100,25 75,0 0,25 75,50" Fill="White"></Polygon>
            </Grid>
</Button>
Векторная кнопка

Понятно, что в данном случае модель вложенного содержимого проще добавления дополнительных свойств в класс Button для поддержки различных видов содержимого. Эта модель не только повышает гибкость, но и позволяет не загромождать интерфейс класса Button. А поскольку все элементы управления содержимым поддерживают точно такое же вложение содержимого, то отпадает необходимость добавлять различные свойства содержимого в различные классы. (Разработчики Windows Forms столкнулись с этой проблемой в .NET 2.0, пытаясь усовершенствовать классы Button и Label для улучшения поддержки изображений и содержимого, объединяющего картинки и текст.)

Вообще-то модель вложенного содержимого является результатом компромисса. Она упрощает модель классов для элементов, поскольку устраняет дополнительные слои наследования и добавление свойств для различных видов содержимого. Но при этом приходится использовать несколько более сложную модель объектов — элементов, которые можно создать из других вложенных элементов.

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

Пройди тесты
Лучший чат для C# программистов