Can WPF themes be used to include multiple skins for an application that can be changed at runtime? Can WPF themes be used to include multiple skins for an application that can be changed at runtime? wpf wpf

Can WPF themes be used to include multiple skins for an application that can be changed at runtime?


Here is a snippet of code that I used in my application that supported theming. In this example, I have two themes (Default and Classic XP). The theme resources are stored in the DefaultTheme.xaml and ClassicTheme.xaml respectively.

This is the default code in my App.xaml

<Application ...>    <Application.Resources>        <ResourceDictionary>            <ResourceDictionary.MergedDictionaries>                <ResourceDictionary Source="ArtworkResources.xaml" />                <ResourceDictionary Source="DefaultTheme.xaml" />            </ResourceDictionary.MergedDictionaries>            <Style x:Key="SwooshButton" TargetType="ButtonBase">                <!-- style setters -->            </Style>            <!-- more global styles -->        </ResourceDictionary>    </Application.Resources></Application>

Then in the code behind of the App.xaml I have the following method to allow for changing the theme. Basically, what you do is clear the Resource Dictionaries and then reload the dictionary with the new theme.

    private Themes _currentTheme = Themes.Default;    public Themes CurrentTheme    {        get { return _currentTheme; }        set { _currentTheme = value; }    }    public void ChangeTheme(Themes theme)    {        if (theme != _currentTheme)        {            _currentTheme = theme;            switch (theme)            {                default:                case Themes.Default:                    this.Resources.MergedDictionaries.Clear();                    AddResourceDictionary("ArtworkResources.xaml");                    AddResourceDictionary("DefaultTheme.xaml");                    break;                case Themes.Classic:                    this.Resources.MergedDictionaries.Clear();                    AddResourceDictionary("ArtworkResources.xaml");                    AddResourceDictionary("ClassicTheme.xaml");                    break;            }        }    }    void AddResourceDictionary(string source)    {        ResourceDictionary resourceDictionary = Application.LoadComponent(new Uri(source, UriKind.Relative)) as ResourceDictionary;        this.Resources.MergedDictionaries.Add(resourceDictionary);    }

What you'll also need to keep in mind with this approach is that any styles that utilize a theme will need to have a dynamic resource. For example:

<Window Background="{DynamicResource AppBackgroundColor}" />


I don't know of a way of doing this in the framework, but you can do it if you style every control that can change yourself.

The theory is to make the style a DynamicResource and then load the ResourcesDictionary based on the users configuration for the different style.

Here is an article that has an example.