Adding Custom Themes Support to your WPF Application

November 17, 2008 03:41 by ndibek

The greatest thing about Windows Presentation Foundation is that when compared to Windows Forms, it finally gives us the freedom of easily designing rich UI, that differs from same old Winforms we have been seeing from Win 95 with slight re-styling. We finally have a true vector based UI, that allows us to manipulate each screen element in thousands of different ways through visual effects, animations, scaling, custom layouts etc.

But with this Great Power comes even larger responsibility. Yes we can do all these things, but we also need to assure that our UI looks consistent: If we find this really cool looking buttons library, we need to assure that the Tree Control that we render next to it is styled appropriately to match it, as well as list box, check boxes scroll bars...

We do not want our new UIs to be a mix of every color in the rainbow that look like water color painting of a kindergartner. We need a professional 21st century UIs. Unfortunately most of us developers are superbly creative when it comes to complex algorithms, while our artistic skills lack far behind. Third party controls that support custom Themes might have been a solution to this problem in Windows Forms world, but do we really have to go there in WPF? Another great thing with WPF it adds native support for custom themes. Basically you define your basic layout, drop your controls on the screen, and then similar to CSS in the web world, you define custom styles for your control in the Resources section of your XAML code. If only we had a nice library of WPF styles that we could use...

 



Well that is where "WPF Themes" Library - Open Source Project hosted on CodePlex comes in.  First it is a library of a dozen custom UI Themes for most of the standard WPF controls, allowing us to customize the look and feel of our WPF UI without touching our screens XAML.  What more the library actually comes with a Theme Manager, that allows us to dynamically load and bind our custom Themes at runtime.

How can we use these Themes?  Obviously first download WPF Themes Library project from http://www.codeplex.com/wpfthemes and include it in your WPF Solution. Then it is a matter of you deciding how do you want to select and load custom Theme at runtime.  For the purpose of this example lets presume that we want to allow our Application user to select any of these Themes at runtime in a form of the Drop Down box that we place at, lets say, top right corner of the application main screen.

So lets define this DropDown:


    
    

Ok, so if we look at the XAML above you will notice that there is a stack panel that encapulates the label and a DropDown. But wait, there is no event handler for the SelectionChanged event! How do we tell this WPF Theme library to load a theme we select from the DropDown? Well, if we take a look at the source code of the ThemeManager class that is in charge of loading Themes for us, you will notice that it defines/registers a Dependency Property called "Theme". What does that mean? It means that we can just add this propery to our root window, and bind it to the drop down selection, and that is it. Each time we change a selection in our Drop down list of available themes, ThemeManager loads that Thema and applieas it to our WPF application. The two lines of XAML that allow us to define our dependency property are listed below:



    ...


Now the last question is: How do we populate the "Available Themes" Drop Down list? We simply bind it to ThemeManager.GetThemes(), like below:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    themes.ItemsSource = ThemeManager.GetThemes();
}

And simply put - that is it, by placing the code above together with WPF.Themes project in your solution you get great set of WPF themes, that you can simply use in your app, but also customize and extend.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5