Override or customize WPF themes such as PresentationFramework.Aero

by Geert 20. July 2009 15:37

WPF is a great technology to use when developing applications for Windows. However, styling is one of the things I think should be made easier. For example, the “Vista” look (a.k.a. Aero) looks great, except that you will have to style all the controls yourself if you want some reasonable spacing between your control. For example, take a look at the following screenshot that uses the Aero style without any modifications:

overridestyles_aero_default

Figure 1 – Default Aero style

I think we all agree that the margins between the controls are a little small, too small. Now there are several things we can do to increase the margins of the Aero theme (or any other available theme):

  1. Export the Aero theme from the PresentationFramework.Aero assembly and customize it
    I wouldn’t recommend this option, unless you like to read through 250 kb of styles.
  2. Define all styles again in a new style, based on the default style as it is defined in PresentationFramework.Aero, and give it a key like “DefaultxxxStyle”, where xxx is replaced by the control type name. Then, you will have to add the style declaration to every control like this:
    <Control Style=”{StaticResource DefaultControlStyle}” />. Get’s kind of dull, not, but this is the way to go.
  3. Use the StyleHelper, which automates the method described at step 2.

You must think now: why not simply re-define the style and set the margin like this:

<Style x:Key="Button" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property=”Margin” Value=”6” />
</Style>

Well, then you will get circular references, since the Button style you define is based on the style Button, which is defined as Button, which is based on Button, etc.

Overriding style using the StyleHelper class

The StyleHelper class has a few static members that will create style forwarders. Style forwarders are styles that are defined on application level, not on theme level. This allows you to create forwarders with the same key as the control name, but that will forward to the DefaultxxxStyle. Since the new styles are defined at application level, you will not get any circular references because the style defined in the theme cannot access the application level resources.

Using the StyleHelper class, you can customize any existing theme without too much of a hassle. Below are 2 examples of a customized version of the Aero theme (the only differences are the margins).

overridestyles_aero_large

Figure 2 – Customized Aero theme (large margins)

overridestyles_aero_normal

Figure 3 – Customized Aero theme (normal margins)

As you can see, the margins between the controls are automatically applied. This is accomplished by simply calling StyleHelper.CreateStyleForwardersForDefaultStyles(); in the OnStartup of the WPF application.

The attached demo application shows you an example how to use the StyleHelper class.

Downside of the StyleHelper class

The StyleHelper class currently has only one downside, and that is that it is not supported at design time in Visual Studio. However, the designer of Visual Studio breaks anyway as soon as you want to do something fancy, so who uses that thing anyway?

OverrideStyles.zip (14.91 kb) [Downloads: 905]

kick it on DotNetKicks.com

Easily customize or override existing WPF themes with the StyleHelper class

Tags:

WPF

Pingbacks and trackbacks (2)+

Comments are closed

About the Author

Geert van Horrik is an independent freelance software developer since January 1st, 2007. Since then he was been working on several projects from C++ to C# (WPF, Silverlight, ASP.NET, etc). Currently he loves to write his software using WPF (or Silverlight if WPF isn't an option).

Lately, Geert is spending a lot of time on Catel, a free open-source MVVM Framework for WPF and Silverlight. Actually, it's more than "just" an MVVM Framework, it's a complete application library!