WPF FAQ - Styles and Templates

Find answers for the most frequently asked questions
Expand All Collapse All

Here is how you would access a Canvas.Left extended property for example:


        <DataTemplate x:Key='MyTemplate1'>
            <Path Data='{Binding Geometry}'>
                <Path.RenderTransform>
		<!-- The Item property returns a visual hosted inside the Canvas -->
                    <RotateTransform Angle='60' CenterX='{Binding Item.(Canvas.Left)}' 
                                     CenterY='{Binding Item.(Canvas.Top)}' 
                                     >
                    </RotateTransform>
                </Path.RenderTransform>
            </Path>
        </DataTemplate>
Permalink

Perhaps you want your two ‘TextBlock’ elements to share some property values such as the FontFamily and the centered HorizontalAlignment, but you also want the text ‘My Pictures’ to have some additional properties. You can do that by creating a new style that is based on the first style, as shown here.

[XAML]

<Window.Resources>

...

<!--A Style that extends the previous MyBaseStyle Style-->
<!--This is a 'named style' with an x:Key of MyDerivedStyle-->
<Style BasedOn='{StaticResource {x:Type MyBaseStyle}}'
       TargetType='TextBlock'
       x:Key='MyDerivedStyle'>
  <Setter Property='FontSize' Value='26'/>
  <Setter Property='Foreground'>
  <Setter.Value>
      <LinearGradientBrush StartPoint='0.5,0' EndPoint='0.5,1'>
        <LinearGradientBrush.GradientStops>
          <GradientStop Offset='0.0' Color='#90DDDD' />
          <GradientStop Offset='1.0' Color='#5BFFFF' />
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </Setter.Value>
  </Setter>
</Style>

Permalink

If you want to enforce that a style can be applied to a particular type only, you can set its ‘TargetType’ property.

For example, the following style can only be applied to a button (or a subclass of a button).

[XAML]

<Style x: key='buttonStyle' TargetType='{x:Type Button}'>
	<Setter Property=' Button.FontSize' Value='22'/>
	<Setter Property=' Button.Background' Value='Purple'/>
	<Setter Property=' Button.Foreground' Value='While'/>
	<Setter Property=' Button.Height' Value='50'/>
	<Setter Property=' Button.Width' Value='50'/>
	<Setter Property=' Button.RenderTransFormOriginal' Value='.5,.5'/>
	<Setter Property=' Button.RenderTransForm'/>
	<Setter.Value >
		<RotateTransform Angle='10'/>
	</Setter.Value>
	</Setter>
</Style>
Permalink

In Extensible Application Markup Language (XAML), style and template properties can technically be set in any one of two ways provided. You can use ’attribute syntax’ to reference a style that was defined within a resource, for example <object Style='{StaticResource myResourceKey}’ …/>. Or you can use ’property element syntax’ to define an inline style for an instance.

[XAML]

<object>

<object.Style>

<Style .../>

</object.Style>

</object>

The attribute usage is much more common. A style that is defined inline and not defined in resources is necessarily scoped to the containing element only and cannot be re-used easily because it has no resource key. In general a resource-defined style is more versatile and useful in keeping with the general Windows Presentation Foundation (WPF) programming model principle of separating program logic in code from design in markup.

Usually there is no reason to set a style or template inline even if you intend to use that style or template in that location only. Most elements that can take a style or template also support a ’content property’ and a ’content model’. If you only use the logical tree you create through styling or templating once, it would be even easier to just fill that content property with the equivalent child elements in direct markup. This would bypass the style and template mechanisms altogether.

Other syntaxes enabled by markup extensions that return an object are also possible with styles and templates. Two such extensions that have possible scenarios include ’TemplateBinding’ and ’Binding’.

Permalink

The WPF theme engine will switch styles automatically for you if you place them in separate ’ResourceDictionary’ XAML files compiled in your application.

The files need to be named.

themes\..xaml

For example, these are the themes that Microsoft produces.

themes\luna.normalcolor.xaml

themes\luna.homestead.xaml
themes\luna.metallic.xaml
themes\royale.normalcolor.xaml
themes\aero.normalcolor.xaml

The case for classic is slightly different.

themes\classic.xaml

Windows Presentation Foundation does not provide an event to notify the user regarding theme changes. If you need to go beyond what is provided by styles in a ResourceDictionary, you will need to listen to the ’WM_THEMECHANGE’ message in a window hook.

Permalink

The ControlTemplate specifies the appearance of a Control. If a Control does not have a ControlTemplate, the Control will not appear in your application. The control author defines the default control template and the application author can override the ControlTemplate to redefine the visual tree of the control. A ControlTemplate is intended to be a self-contained unit of implementation detail that is invisible to outside users and objects, including Style objects. The content of the ControlTemplate can be manipulated within the same ControlTemplate only.

The following example creates a ControlTemplate for a Button. If you add this to your application as a resource, all the buttons in the application will appear as ellipses but will still function as buttons.

[XAML]

<Style TargetType='Button'>
  <!--Set to true to not get any properties from the themes.-->
  <Setter Property='OverridesDefaultStyle' Value='True'/>
  <Setter Property='Template'>
    <Setter.Value>
      <ControlTemplate TargetType='Button'>
        <Grid>
          <Ellipse Fill='{TemplateBinding Background}'/>
          <ContentPresenter HorizontalAlignment='Center'
                            VerticalAlignment='Center'/>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.