Апр 02
Введение
Элементы управления в WPF разделяются на: логику, которая определяет состояния, события, свойства и шаблоны, которые отвечают за визуальную часть элемента управления. Связь между логикой и шаблонами осуществляется при помощи привязок.
Каждый элемент управления имеет шаблон по умолчанию. Это позволяет элементам обладать изначальной внешностью. Шаблон по умолчанию, как правило, поставляется сразу с самим элементом и, как правило, доступен из общего окна шаблонов. Получается условно так, что элемент завернут в стиль, который определен при помощи значения свойства DefaultStyleKey и является неотъемлемой частью каждого элемента управления.
Шаблон определен при помощи зависимого свойства, названного «Template». Устанавливая это свойство на другой экземпляр шаблона, вы можете полностью заменить внешность (визуальное дерево) элемента управления.
Шаблон управления часто включен внутрь стиля, который в свою очередь содержит настройки других свойств. В следующем примере кода показан простой шаблон управления, применительно для кнопки, имеющей форму эллипса.
<Style x:Key="DialogButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Style="{StaticResource DialogButtonStyle}" />
ContentPresenter
При создании произвольного шаблона управления, когда необходимо создать плэйсхолдер (заместитель), который будет отвечать за внутренние содержимое, возможно прибегнуть к использованию «ContentPresenter». По умолчанию он добавляет содержимое «Content Property» к визуальному дереву в самом шаблоне. Чтобы отобразить содержимое другого свойства необходимо установить необходимое имя свойства для ContentSourse.
Триггера
{RelativeSource TemplatedParent} не работает в триггерах данных внутри шаблона управления
Если вы хотите привязаться к свойству свойства элемента управления, например как Data.isLoaded вы не сможете использовать обычный триггер, по крайней мере, такая нотация не поддерживается. Так что старайтесь использовать DataTrigger.
Но когда используется DataTrigger, совместно с {RelativeSource TemplatedParent}, что-то не срабатывает. Причина в том, что TemplatedParent может быть использован только в ControlTemplate. Дело в том, что это не будет работать с триггерными секциями. За место этого необходимо использовать {RelativeSource Self}.
Что делать если привязка работает или сеттер отказывается срабатывать при использовании шаблона управления
Существует кое-что, что необходимо знать при установке значения какому-либо элементу внутри элементе управления шаблоном: значение имеет нижний приоритет, если это локальное значение. По этому, если вы устанавливаете локальное значение в конструкторе содержащего элемента, вы не можете изменить его в шаблоне управления. Но если используется элемент непосредственно из дизайнера, то это сработает. Так что будьте в курсе такого поведения!
Найти более подробную информацию о «DependencyProperty» можно перейдя по ссылке: Приоритет значений зависимых свойств.