Нашли ошибку или опечатку? Выделите текст и нажмите

Поменять цветовую

гамму сайта?

Поменять
Обновления сайта
и новые разделы

Рекомендовать в Google +1

UserControl

64

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

"За кулисами" класс UserControl работает во многом подобно классу ContentControl, от которого он унаследован. В действительности ключевых отличий немного:

  • Класс UserControl изменяет некоторые значения по умолчанию. А именно: устанавливает IsTabStop и Focusable в false (так что он не занимает отдельного места в последовательности обхода по клавише <Tab>), а также устанавливает HorizontalAlignment и VerticalAlignment в Stretch (вместо Left и Тор), в результате заполняя все доступное пространство.

  • Класс UserControl применяет новый шаблон элемента управления, состоящий из элемента Border, который упаковывает ContentPresenter. Элемент ContentPresenter хранит в себе содержимое, которое добавляется посредством кода разметки.

  • Класс UserControl изменяет источник маршрутизированных событий. Когда событие распространяется пузырьком или туннелируется от элемента управления, находящегося внутри пользовательского элемента, к элементу, находящемуся вне его, источник изменяется и указывает на пользовательский элемент управления вместо первоначального элемента. Это немного повышает степень инкапсуляции.

    Например, при обработке события UIElement.MouseLeftButtonDown в контейнере компоновки, содержащем в себе созданный ранее указатель цвета, будет получено событие, когда выполняется щелчок кнопкой мыши внутри Rectangle. Однако источником этого события будет не Rectangle, а объект ColorPicker, содержащий этот Rectangle. Если создать тот же самый указатель цвета как обычный элемент с содержимым, то этого не будет — в данном случае на вас возлагается обязанность перехватывать событие в элементе управления, обрабатывать его и возбуждать повторно.

Наиболее существенное отличие пользовательских элементов от других типов специальных элементов управления заключается в способе их проектирования. Как и все элементы управления, пользовательские элементы имеют шаблон. Однако этот шаблон изменяется редко. Вместо этого создается код разметки как часть класса специального пользовательского элемента управления, и этот код разметки обрабатывается с применением метода InitializeComponent() при создании элемента. С другой стороны, элемент управления, не имеющий внешнего вида, не имеет и разметки. Все, что ему нужно — это шаблон.

Обычный ContentControl имеет следующий упрощенный шаблон:

<ControlTemplate TargetType="ContentControl">
   <ContentPresenter
      ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
      Content="{TemplateBinding ContentControl.Content} " />
</ControlTemplate>

Этот шаблон всего лишь наполняет полученным содержимым и применяет необязательный шаблон содержимого. Свойства вроде Padding, Background, HorizontalAlignment и VerticalAlignment не дают никакого эффекта, если только явно не привязать их.

UserControl имеет похожий шаблон, но с несколькими дополнительными тонкостями. Наиболее очевидно то, что он добавляет элемент Border и привязывает его свойства к свойствам BorderBrush, BorderThickness, Background и Padding пользовательского элемента управления, чтобы они что-нибудь делали. Вдобавок ContentPresenter внутри привязывается к свойствам выравнивания.

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

Пройди тесты