Why is the key x required in the ControlTemplate in the ResourceDictionary file:

Consider the following XAML file:

<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> 

This results in the following compilation error:

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

If I add the x:key attribute to the ControlTemplate, it compiles. However, I should not have done this. The ControlTemplate is decorated with the DictionaryKeyProperty attribute, which defines TargetType as a key property. As long as I specify a TargetType for my ControlTemplate, I must not specify an explicit key (similar to how I should not specify one of the specified DataTemplate).

I have a second and tangent question. If I define a ControlTemplate this way (either by specifying a key or not) in XAML, does it automatically apply to all controls like ContentControl that don't specify another template, or will I need to insert a ControlTemplate inside the style for this?

+6
source share
4 answers

From the MSDN ControlTemplate :

If the resource section has a stand-alone ControlTemplate control that has the TargetType property set by the type, the ControlTemplate does not automatically apply to this type. Instead, you need to specify x: Key and apply the template explicitly.

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

So, the ControlTemplate not applied automatically, and you should always specify x:Key . Therefore, DictionaryKeyProperty not applicable.

I did some research:

Although the MSDN DictionaryKeyPropertyAttribute page says:

WPF Usage Notes

The following list provides examples of the WPF APIs in which this attribute is applied:

 ControlTemplate.TargetType DataTemplate.DataTemplateKey Style.TargetType 

But the Resource Overview page only mentions Styles, DataTemplates, and Implicit Keys , which has implicit keys. It also means that you always need to specify x:Key for the ControlTemplate , despite the DictionaryKeyProperty .

By the way, something is wrong with DictionaryKeyPropertyAttirubte see this connection problem .

+4
source

I do not know the answer to your first question, but about the second:

I have a second and tangent question. If I define a ControlTemplate this way (either specify a key or not) in XAML, does it automatically apply to all controls like ContentControl that don't specify another template, or will I have to embed a ControlTemplate inside the style for this?

No, it will not be automatically applied. Styles are applied automatically if their key matches the control's DefaultStyleKey element; Data templates are automatically selected using ContentControl if the Content type matches the DataType template. But this is not the case for management templates; in any case, control patterns are usually defined as part of a control style; they are rarely applied directly to a control.

+1
source
 <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> 

The key is used to apply patterns to the control, such as a button, text field, text block, etc. If you do not use it, then the template does not work.

0
source

If you want the control template to be applied to the entire specified type, you can define the style and set the Template property and this style from TargetType to the control you specify:

 <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> 

I tested this with the targettype button, but I think it should work that way.

0
source

Source: https://habr.com/ru/post/909900/


All Articles