Элемент ContentControl

87

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

Все контейнеры Silverlight наследуют класс Panel, предоставляющий им возможность содержать много элементов. В то же время все элементы, способные содержать только один элемент, наследуют класс ContentControl. Иерархия классов показана на следующей диаграмме:

Иерархия наследования элементов ContentControl

Как видно, несколько самых популярных элементов управления фактически являются элементами ContentControl, включая ToolTip, Button, RadioButton и CheckBox. Есть также специальные элементы ContentControl, такие как ScrollViewer. Некоторые элементы ContentControl предназначены для использования с другими, специальными элементами. Например, элемент ListBoxItem должен быть вложен в ListBox.

Свойство Content

Обратите внимание на то, что в классе Panel определена коллекция Children, содержащая вложенные элементы, а в классе, наследующем ContentControl, определено свойство Content, содержащее один объект. Свойство Content может содержать объект любого типа, благодаря чему существуют три способа вывода содержимого:

Рассмотрим простую кнопку. Для генерации ее содержимого достаточно простой текстовой строки:

<Button Margin="5" Content="Простая кнопка"/>

Однако в кнопку можно поместить и другие, более сложные элементы. Например, с помощью класса Image в кнопку можно поместить изображение:

<Button Margin="5">
      <Image Source="myimage.png" Stretch="None"/>
</Button>

В кнопку можно также поместить изображение и текст, заключив их в какую-либо оболочку, например в контейнер StackPanel.

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

Какие преимущества предоставляют элементы ContentControl по сравнению с обычными? Ведь в кнопку можно поместить изображение. Не достаточно ли этого? Однако модель вложения содержимого все же имеет ряд важных преимуществ.

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

Модель векторных изображений плавно интегрируется в модель вложенного содержимого элементов ContentControl, поскольку они могут содержать любые элементы. Например, приведенная ниже разметка создает простую графическую кнопку, содержащую векторное изображение:

<Button Margin="5" Height="100" Width="100" Background="DarkOrange">
            <Grid>
                <Path Stretch="Fill" Stroke="LimeGreen" Fill="LimeGreen" 
                      Data="F1 M 23.25,9.10939C 23.25,13.1094 21.5,16.8594 21.5,15.8594C 21.5,14.8594 19.5,18.8594 
                            18.5,20.8594C 17.5,22.8594 16.5,25.6094 16.5,25.6094L 12.5,25.3594C 12.5,25.3594 11.5,34.1094 
                            13.5,35.1094C 15.5,36.1094 17.5826,34.7089 19.5,35.8594C 24.5,38.8594 32.5,36.8594 31.5,34.8594C 
                            31.5,34.8594 35.5,32.8594 34.5,31.8594C 34.5,31.8594 35.5,30.3594 34.25,28.8594C 35.5,27.3594 
                            35,25.8594 34.25,24.8594C 35,23.3594 35.5,21.8594 32.5,20.8594C 30.6026,20.2269 25.5,22.6094 
                            25.5,19.8594C 25.5,18.8594 27.5,15.8594 27.5,13.8594C 27.5,9.85939 23.25,9.10939 23.25,9.10939 Z"/>
            </Grid>
</Button>
Векторная кнопка

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

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

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

Выравнивание содержимого

Выравнивание содержимого выполняется с помощью свойств HorizontalContentAlignment и VerticalContentAlignment.

Для свойств HorizontalContentAlignment и VerticalContentAlignment доступны те же значения, что и для HorizontalAlignment и VerticalAlignment. Это означает, что содержимое можно выровнять по одному из краев рамки (значения Top, Bottom, Left и Right), центрировать (значение Center) или растянуть, пока оно не заполнит доступное пространство (значение Stretch).

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

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

Свойства HorizontalContentAlignment, VerticalContentAlignment и Padding определены в классе Control, а не в специальном классе ContentControl. Это объясняется тем, что некоторые элементы управления не наследуют класс ContentControl, но все же могут иметь содержимое. Один из примеров такого элемента управления - текстовое поле TextBox. Для включенного в него текста, определяемого свойством Text, нужно каким-либо образом задавать выравнивание и ширину внутренних отступов. Это делается с помощью указанных выше свойств.

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