Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why define a Template inside a Style in xaml, WPF?

I've been wondering this ever since I started using MS's control templates examples as basis to build custom controls.

take the Label example for instance: http://msdn.microsoft.com/en-us/library/ms752327.aspx

why on earth is it defined like this:

<Style x:Key="{x:Type Label}" TargetType="Label">
  <Setter Property="HorizontalContentAlignment" Value="Left" />
  <Setter Property="VerticalContentAlignment" Value="Top" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Label">
        <Border>
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            RecognizesAccessKey="True" />
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground">
              <Setter.Value>
                <SolidColorBrush Color="{DynamicResource DisabledForegroundColor}" />
              </Setter.Value>
            </Setter>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

and not like this directly:

<ControlTemplate x:Key="{x:Type Label}" TargetType="Label">
    <Border>
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                        RecognizesAccessKey="True" />
    </Border>
    <ControlTemplate.Triggers>
      <Trigger Property="IsEnabled" Value="false">
        <Setter Property="Foreground">
          <Setter.Value>
            <SolidColorBrush Color="{DynamicResource DisabledForegroundColor}" />
          </Setter.Value>
        </Setter>
      </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

and then called as a template directly and not through the style property?

is there a hidden reason I do not see for doing things like this? or is it just one way of doing things and that's it?

(NB: don't tell me this is because of the horizontal and vertical alignment setters! we all know those are the default values for a label and this is basically useless if you keep those values)

like image 381
David Avatar asked Feb 02 '11 09:02

David


People also ask

What is the purpose of templates in WPF?

The template connects the visual presentation of the control with the control's capabilities. Because you define a template in XAML, you can change the control's appearance without writing any code. Each template is designed for a specific control, such as a Button.

What is the difference between control template and data template?

A ControlTemplate will generally only contain TemplateBinding expressions, binding back to the properties on the control itself, while a DataTemplate will contain standard Binding expressions, binding to the properties of its DataContext (the business/domain object or view model).

Where is style defined in XAML?

You can use a style on any element that derives from FrameworkElement or FrameworkContentElement such as a Window or a Button. The most common way to declare a style is as a resource in the Resources section in a XAML file.

What is a style in WPF?

Styles provide us the flexibility to set some properties of an object and reuse these specific settings across multiple objects for a consistent look. In styles, you can set only the existing properties of an object such as Height, Width, Font size, etc. Only default behavior of a control can be specified.


1 Answers

Without using a Style it's not possible to automatically assign the template to all instances of a specific control type. Setting x:Key="{x:Type Label}" for the control template does not automatically apply this template to all controls of type Label.

You can make a style apply to all buttons below the declaration in the visual tree by setting the TargetType to Button, but you can't do the same with a template, if you do not wrap it inside a Style that have a Setter for the template.

Also, note that in your example you can exchange

<Style x:Key="{x:Type Label}" TargetType="Label">

With

<Style TargetType="Label">

As the x:Key is set to the TargetType if the x:Key definition is omitted.

like image 177
Øyvind Bråthen Avatar answered Oct 25 '22 02:10

Øyvind Bråthen