Simple Theming for your WPF application

Recently I had a requirement to be able to ‘re-theme’ an application at startup. By this, I mean I needed to change the background image for a WPF application, as well selecting a specific resource dictionary that contains all the styles for buttons, text, labels and all the other controls in the application. It was an interesting problem, but in the end, I found a really simple solution to it.

 

Setting the background image

In the code behind my Window.xaml file, I implemented a check based on a license file that is used in the application. The check simply returns a bool, true for the default theme and false for the alternative theme. To set the background, I then used the following code, with the image files being resources contained within the project.

 if (useDefaultTheme)
 {
          Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/Images/DefaultBackground.jpg")));
 }
 else
 {
          Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/Images/AlternativeBackground.jpeg")));
 }

 

Setting the resource dictionary to use

I have two large resource dictionaries, one that contains styling for the default application presentation and one for the alternative. This solution took me a bit longer to research, but I have to say it works really well, is very simple and could be very easily amended to take in a number of alternative styles. In my App.xaml code behind file, I have the following code. By having this code here it makes the styling application wide.

if (useDefaultTheme)
{
        var commonXaml = new Uri("My.Application;component/Themes/DefaultTheme.xaml", UriKind.RelativeOrAbsolute);
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = commonXaml });
}
else
{
        var commonXaml = new Uri("My.Application;component/Themes/AlternativeTheme.xaml", UriKind.RelativeOrAbsolute);
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = commonXaml });
}

Now my application loads the relevant background and styling at startup, based upon the return value of a boolean check. The check could be tied to a license file, machine name, anything you want. Regardless, the working principle remains the same.