2012-03-03 1 views
6

Рассмотрим следующий XAML файл:Почему х: ключ требуется ControlTemplate в ResourceDictionary

<Window x:Class="ExpressionVisualizer.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type sle:BinaryExpression}"/> 
     <ControlTemplate TargetType="{x:Type ContentControl}"/> 
    </Window.Resources> 
</Window> 

Это дает следующие компиляции ошибка:

All objects added to an IDictionary must have a Key attribute or some other type of key associated with them. Line 10 Position 10.

Если добавить атрибут x:key к ControlTemplate, он компилируется. Однако я не должен был этого делать. ControlTemplate украшен атрибутом DictionaryKeyProperty, который определяет TargetType как свойство ключа. Поэтому до тех пор, пока я укажу TargetType для моего ControlTemplate, я должен указать , а не, чтобы указать явный ключ (аналогично тому, как я не должен указывать один из определяемого DataTemplate).

У меня есть второй и касательный вопрос. Если я определяю ControlTemplate таким образом (либо указывая ключ или нет) в XAML, он автоматически применяется ко всем элементам управления типа ContentControl, которые не указывают другой шаблон, или мне нужно будет вставить ControlTemplate внутри стиля для этого?

ответ

4

Из MSDN ControlTemplate:

If you have a standalone ControlTemplate in the resources section with the TargetType property set to a type, the ControlTemplate does not get applied to that type automatically. Instead, you need to specify an x:Key and apply the template explicitly.

Also note that the TargetType property is required on a ControlTemplate if the template
definition contains a ContentPresenter.

Так ControlTemplate не применяется автоматически, и вы должны всегда указывать x:Key. Таким образом, DictionaryKeyProperty не применяется.

Я сделал некоторые исследования:

Хотя DictionaryKeyPropertyAttribute страниц состояний MSDN:

WPF Usage Notes

The following list references examples of WPF APIs where this attribute is applied:

ControlTemplate.TargetType 

DataTemplate.DataTemplateKey 

Style.TargetType 

Но на Resources Overview странице они только упоминают Styles, DataTemplates, and Implicit Keys, которая имеет неявные ключи. Это также означает, что вам необходимо всегда указывать x:Key для ControlTemplate, несмотря на то, что DictionaryKeyProperty.

Кстати, кажется, что что-то не так с DictionaryKeyPropertyAttirubte см. В этом connect issue.

+0

Это отвечает на вторую часть моего вопроса. Я знаю, что мне нужно указать x: Key, если я хочу ссылаться на шаблон в другом месте документа, но его отсутствие не должно вызывать ошибку компиляции. – luksan

+0

Я обновил свой ответ. Это швы 'DictionaryKeyProperty' не делает то, что должно быть ... – nemesv

+0

Проблема с DictionaryKeyProperty, похоже, не влияет на все типы, так как атрибут работает так, как указано в DataTemplate. Проблема с подключением - с 2009 года. Наверное, я просто напишу это как еще одну вещь в WPF, которая просто не работает и никогда не была тщательно протестирована. Каждый раз, когда я пытаюсь что-то развить в WPF, я сталкиваюсь с этими типами проблем. Это никогда не происходит с Windows Forms, все просто работает. Я действительно думал (возможно, желаю), что они собираются сделать WPF более предсказуемым/полезным в версии 4.0. – luksan

1

Я не знаю ответа на ваш первый вопрос, а о втором:

I have a second and tangentially related question. If I define a ControlTemplate in this way (either specifying a key or not) in the XAML, does it get automatically applied to all controls of type ContentControl that don't specify another template, or would I have to embed the ControlTemplate inside a Style for that to occur?

Нет, он не будет автоматически применяться. Стили применяются автоматически, если их ключ соответствует DefaultStyleKey элемента управления; шаблоны данных выбираются автоматически ContentControl, если тип Content соответствует шаблону DataType. Но это не относится к шаблонам управления; во всяком случае, шаблоны управления обычно определяются как часть стиля элемента управления, они редко применяются непосредственно к элементу управления.

+0

+1 и спасибо, я не знал о DefaultStyleKey. – luksan

0
<Window x:Class="ExpressionVisualizer.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="DT" DataType="{x:Type sle:BinaryExpression}"/> 
    <ControlTemplate x:Key="CT" TargetType="{x:Type ContentControl}"/> 
</Window.Resources> 

Ключ используется для применения шаблона на контроль, как и кнопка, текстовое поле, TextBlock и т.д. Если вы не используете его, то шаблонирования не работает.

0

Если вы хотите, чтобы шаблон управления будет применены ко всему указанному типу можно определить стиль и набор шаблонов собственности и этот стиль с TargetType на указанном вами управление:

<Window x:Class="ExpressionVisualizer.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="DT" DataType="{x:Type sle:BinaryExpression}"/> 
    <ControlTemplate x:Key="CT" TargetType="{x:Type ContentControl}"/> 
    <Style TargetType="ContentControl"> 
     <Setter Property="Template" Value="{StaticResource CT}"></Setter> 
    </Style> 
</Window.Resources> 

Я проверил это с но я думаю, что он должен работать таким образом.

 Смежные вопросы

  • Нет связанных вопросов^_^