views:

741

answers:

2

How can I create a UserControl in WPF that has a basic default style but can also easily themed when needed?

Do you have some good guidelines, blog entries or example that explain this specific topic?

Thank you in advance, Marco

+1  A: 

Look at this article: http://msdn.microsoft.com/en-us/magazine/cc135986.aspx

It talks about how to write a control that you can change with a ControlTemplate, like the built in controls.

Nir
+3  A: 

In WPF themes are simply a set of XAML files each containing a ResourceDictionary which holds the Style and Template definitions that apply to the controls used in the application. A theme file could look like this:

<ResourceDictionary
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:uc="clr-namespace:MyApp.UserControls">

  <!-- Standard look for MyUserControl -->
  <Style x:Key="Standard" TargetType="{x:Type uc:MyUserControl}">
    <Setter Property="Width" Value="22" />
    <Setter Property="Height" Value="10" />
  </Style>

</ResourceDictionary>

Support for themes in a WPF application must be explicitly enabled by adding the following attribute to the assembly:

[assembly: ThemeInfo(
  ResourceDictionary.None,
  ResourceDictionaryLocation.SourceAssembly
 )]

This will instruct WPF to look for an embedded resource file called themes\generic.xaml to determine the default look of the application's controls.

You can find a good sample here. It's somewhat dated, but the concepts are still relevant in the current version of WPF.
The only difference is that when the theme-specific dictionaries are contained separate files than the application's assembly, style and template resources must use a "composite key", which tells WPF which assembly contains the control that the style/template applies to. So the previous example should be modified to:

<ResourceDictionary
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:uc="clr-namespace:MyApp.UserControls;assembly=MyApp">

  <!-- Standard look for MyUserControl in the MyApp assembly -->
  <Style x:Key="{ComponentResourceKey {x:Type uc:MyUserControl}, Standard}">
    <Setter Property="Width" Value="22" />
    <Setter Property="Height" Value="10" />
  </Style>

</ResourceDictionary>
Enrico Campidoglio