views:

27

answers:

1

I have a simple WPF application I'm using for experimenting.

I have two themes defined in seperate xaml files, changing the xaml to point to them worked fine. By the way, in the xaml I'm using a straight ResourceDictionary element, not a ResourceDictionary.MergedDictionaries one.

I want to let the user select which theme to use, so I'm reseting the source property in code behind - but whilst the debugger tells me I've successfully set the value the applications appearance doesn't change.

So, how do you successfully apply a theme at runtime?

EDIT: This is how I'm declaring my "style" in the xaml:

<Window x:Class="WpfUI.winMain">
  <Window.Resources>
    <ResourceDictionary Source="Themes\Blah.xaml"></ResourceDictionary>
  </Window.Resources>

  // The windows grid and other controls...

</Window>
A: 

Hey :)
The simple answer is, you need to clear the applications merged resource dictionaries. Here is some code to get you started

ResourceDictionary dictionary = GetThemeResourceDictionary(yourTheme) 

if (dictionary != null)
{
     App.Current.Resources.MergedDictionaries.Clear();
     App.Current.Resources.MergedDictionaries.Add(dictionary);
}

public ResourceDictionary GetThemeResourceDictionary(string theme)
{
    if (theme != null)
    {
        Assembly assembly = Assembly.LoadFrom("WPF.Themes.dll");
        string packUri = String.Format(YourThemeFolder/{0}.xaml", theme);
        return Application.LoadComponent(new Uri(packUri, UriKind.Relative)) as ResourceDictionary;
    }
    return null;
}

If you want a really nice packaged solution, i would reccommend WPF themes. It introduces a ThemeManager class and a set of built in themes which are really incredible. If you have any difficulty installing it or adding a new theme, contact me :)

TerrorAustralis
Cool - thanks! Let me check it out.
Adrian K
Hmm - doesn't seem to work for me - is it how I'm specifiying the ResourceDictionary in the xaml? (I've since added it to the question - sorry it's not on this machine so not easy to copy the whole code across)
Adrian K
AAh kk i got ya. the problem is, this solution is meant to apply the theme application wide. A few things to check out. First, verify that you are getting the resource dictionary back. Second, replace App.Current.Resouces with WPFui.winMain.Resources. You want to clear the resources that you have on that particular window. I would reccomend applying a style application wide tho. You can do this by using Application.Resources.
TerrorAustralis
Yes it was I'm getting the RD back, and yes the style is being applied - but not consistently. I'll experiment some more and ask some more questions later :)
Adrian K
Check the controls that are not getting the style applied. tell me if any of these patterns are true: Has explicit template defined for control. Are all of same type (eg all buttons are not getting the style). IF 1) then its a matter of style precedence. If 2 then check the style to see if the applied style has a key as well as a type
TerrorAustralis
FYI - I was using Style="{StaticResource ...}" when I should have been using Style="{DynamicResource ...}"
Adrian K