WPF FAQ - Styles and Templates

How do I access extended properties from a XAML tempalte?

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
How can I create a Style deriving from another Style

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
How do I see the templates used by the WPF framework controls?

Here is a very good tool put togather by Chris Sells and Ian Griffiths that shows the templates corresponding to each control in the Presentation Framework dll:

ShowMeTheTemplate

Permalink
How can I restrict the use of style for certain types of controls ?

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
What are the limitations of Inline Styles and Templates ?

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
How can I create a custom WPF button whose look and feel depends on the Windows desktop theme currently in use. How do I get notified when the user changes the theme?

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
How can I set a ControlTemplate in the style template?

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