Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

Dynamically swapping *Shared project* WPF Themes (Styles) at runtime

$
0
0

Hi, this is very closely related (and expands upon) to my last question at

http://social.msdn.microsoft.com/Forums/vstudio/en-US/5ac5ecf6-4b13-4e87-91d7-0caf848dbd6a/dynamically-swapping-local-project-wpf-themes-styles-at-runtime

but this time is looking at a different method/task, so thought warrented a separate thread.

So, like in my last post, I want to swap some styling ("themes") at runtime.

However, after some other discussion, I now want to have all of my resources in a shared project just for the resources, and to be able to swap some of them in here.

I have a new attached sample application here.. (last time I missed some files, this one should be complete)

https://dl.dropboxusercontent.com/u/30760237/ThemeSwap2.zip

This resource project is called Common.

In here, the AppStyles.xaml will contain the resources referenced by application App.xaml, an hence used by all the other views..

So if you look in App.xaml, we will see.

<Application x:Class="ThemeSwap2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="/Common;component/Styles/Appstyles.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources></Application>

Some properties will be common among all themes, and some I will want to swap per theme, so these "themed" properties will be located in the MergedDictionary...

<ResourceDictionary.MergedDictionaries><ResourceDictionary Source="/Common;component/Styles/Themes/LightTheme.xaml"/></ResourceDictionary.MergedDictionaries>

Now, in AppStyles.xaml, I will create the actual styles, and some of these will use some resources from the "Themed" dictionary eg...

<Style x:Key="PromptStyle" TargetType="TextBlock"><Setter Property="FontSize" Value="26"></Setter><Setter Property="Foreground" Value="{DynamicResource PromptForeground}"/><Setter Property="Background" Value="{DynamicResource PromptBackground}"/></Style>
Above, you can see that I have one fixed property (FontSize), but then 2 (fore and back colors) I want to swap at runtime

Now, the main application will swap this merge dictionary (eg see MainWindow.Button_Click..)

private void Button_Click(object sender, RoutedEventArgs e)
    {      
      ResourceDictionary resources = App.Current.Resources.MergedDictionaries.First();
      resources.MergedDictionaries.RemoveAt(0);
      string path = string.Format("/Common;component/Styles/Themes/{0}.xaml", "DarkTheme");
      resources.MergedDictionaries.Insert(0, new ResourceDictionary
      {
        Source = new Uri(path, UriKind.RelativeOrAbsolute)
      });
    }

In AppStyles.xaml I have a style "PromptStyle", and I use this in one of the application Views (see View1 in Module1)...

<Grid><TextBlock Style="{DynamicResource PromptStyle}" Height="40" Width="180">Test</TextBlock>    </Grid>
This picks up the default theme (LightTheme.xaml) fine, however, when you click the button, and swap the dictionary in AppStyles.xaml, the new dynamic styles (the colors) are not updated.

Does anyone know why this is not picked up? Is it because I have a nested dictionary, and this won't work this way (I have used DynamicResources everywhere I think I should)

Any help would be greatley appreciated!

Thanks in advance, Peter




Viewing all articles
Browse latest Browse all 18858

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>