views:

149

answers:

2

I am applying "themes" to my WPF app by clearing all merged dictionaries (Resources.MergedDictionaries.Clear()) and new ones based on the selected theme.
Instead of clearing all dictionaries, I would like to clear only certain "theme-related" dictionaries, leaving others still loaded. How can I do that? I didn't find a way to differentiate dictionaries when iterating though them...

Thanks for your help!

A: 

I'm assuming you're doing the merging at the Application level, otherwise you could just introduce an intermediate control whose only job is to host the theme dictionaries. That being the case, I would suggest using a multi-tiered approach whereby the first merged dictionary houses all theme-related dictionaries:

<Application.Resources>
 <!-- all application level resources -->
 <ResourceDictionary>
  <ResourceDictionary.MergedDictionaries>
   <!-- theme-related resources -->
   <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
     <!-- merge in theme-related dictionaries here -->
    </ResourceDictionary.MergedDictionaries>
   </ResourceDictionary>

   <!-- merge in other application-level dictionaries here -->
  </ResourceDictionary.MergedDictionaries>

  <!-- other resources -->
  <SolidColorBrush x:Key="Foo">Black</SolidColorBrush>
 </ResourceDictionary>
</Application.Resources>

Now you can target only theme-related resources with code like this:

Application.Current.Resources.MergedDictionaries[0].Clear();
Application.Current.Resources.MergedDictionaries[0].Add(...);

HTH, Kent

Kent Boogaart
Very nice. Thanks a lot Kent!!!
Gustavo Cavalcanti
Is there a way to give a resource dictionary a name so you can search for it rather than hard code it as the first one? Or is this considered an acceptable coupling between the XAML and code?
Jamie Penney
A: 

Kent, I accepted your suggestion because it seems obviously correct, but it did not work for me. I have my Application.Resources set as following:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <!--Themes-->
                    <ResourceDictionary Source="pack://application:,,,/Themes;component/ThemeGreenResources.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

When I do this, the app gets the Green theme but this.Resources.MergedDictionary is empty, therefore, not allowing me to access the MergedDictionary inside the main MergedDictionary. What am I missing?

I thought one other option would be to create a class inheriting from ResourceDictionary called ThemeDictionary, and, use it instead ResourceDictionary on the resource files. Then I could iterate through them and only clear the ones whose types are ThemeDictionary. Is this too much of a hack?

Thanks for your help.

Gustavo Cavalcanti