WPF ControlTemplates должен иметь TargetType или нет? - PullRequest
10 голосов
/ 03 сентября 2010

Требуются ли для ControlTemplates в WPF тип TargetType? Я рестайлинг некоторых элементов управления и замечаю, что comboboxitem, listiviewitem и listboxitem имеют один и тот же шаблон:

    <ControlTemplate x:Key="ListBoxItemCT" TargetType="{x:Type ListBoxItem}">

    <Border x:Name="Bd" 
        SnapsToDevicePixels="true" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        Padding="{TemplateBinding Padding}"
        CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
            />
    </Border>

</ControlTemplate>

Можно ли просто удалить TargetType и иметь один шаблон для всех трех? Я пытаюсь сделать это, но получаю странные ошибки и проблемы. Я не могу найти какой-либо конкретной ссылки, что ControlTemplates должен иметь тип.

Ответы [ 2 ]

15 голосов
/ 03 сентября 2010

Для TargetType не требуется, но если вы его не укажете, он будет вести себя так же, как если бы вы указали TargetType для Control. Основное преимущество, которое дает указание типа, - это доступ ко всем свойствам зависимостей этого типа в таких вещах, как TemplateBindings и Triggers без необходимости квалифицировать свойство с типом владельца. Без TargetType вы также можете потерять неявные привязки, например ContentPresenter, к свойству ContentControl.Content. После того, как вы укажете TargetType, этот шаблон может быть применен только к элементам управления этого типа или производным от этого типа. Для обмена между различными типами просто укажите общий базовый класс - в данном случае ContentControl.

Следующие простые шаблоны дадут тот же базовый результат, но первый предпочтительнее и более распространен:

<ControlTemplate x:Key="CommonContentTemplate" TargetType="{x:Type ContentControl}">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Border>
</ControlTemplate>

Без типа все свойства контента необходимо связать вручную:

<ControlTemplate x:Key="CommonTemplate">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          Content="{TemplateBinding ContentControl.Content}"
                          ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                          ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}"
                          ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"/>
    </Border>
</ControlTemplate>
2 голосов
/ 03 сентября 2010

Все они происходят от System.Windows.Controls.ContentControl, так что вы можете выбрать вместо этого.

...