Dynamic Styles

In this post, I will show my attempt to change the Theme of SL application without reloading the app.
you can see a demo here . There are 3 main steps

1. Isolate all the styles into individual files .xaml or xml
2. load all the resources and save them
3. clear the Application Resources before the content is initialized

I modified the Red and Flat styles from Corrina http://blogs.msdn.com/corrinab/archive/2008/06/16/8602865.aspx) to include namespaces on all of them

It allows switching between 3 themes.

Here are the screenshots


The main(page.xaml) content is as follows

<Grid x:Name=”LayoutRoot” >     
        <ContentControl x:Name=”cc1″ Width=”700″ Height=”500″/>
        <ContentControl x:Name=”cc2″
                        Width=”300″
                        Height=”50″
                        HorizontalAlignment=”Right”
                        VerticalAlignment=”Top” />
    </Grid>

cc2 is the ContentControl into which usercontrol(ThemeSelection) will be loaded. cc1 is the ContentControl into which the actual content will be loaded

The codebehind(page.xaml.cs) constructor has the following

 public Page()
        {
            IsolatedStorageSettings.ApplicationSettings.Clear();
         
            GetThemes(“Default”);
            GetThemes(“Red”);
            GetThemes(“Flat”);
            InitializeComponent();
            LayoutRoot.Background = App.Current.Resources[“BkgBrush”] as SolidColorBrush;
           
            ThemeSelection ts = new ThemeSelection(“DefaultTheme”);
            cc2.Content = ts;
            ts.ThemeChanged += new ThemeSelection.ThemeChangedEventHandler(ts_ThemeChanged);
            MainContent mc = new MainContent();
            cc1.Content = mc;
                    
        }
what we are doing is clearing the ApplciationSettings, getting styles for different themes using StreamResourceInfo and populating a list which inturn is added to ApplicationSettings. When the theme is changed the Usercontrol(where we make the theme selection), raises an event which is handled  like this

 void ts_ThemeChanged(object sender, ThemeChangedEventArgs e)
        {           
            ThemeSelection ts = new ThemeSelection(e.Theme);
            cc2.Content = ts;
            MainContent mc = new MainContent();
            cc1.Content = mc;
            ts.ThemeChanged += new ThemeSelection.ThemeChangedEventHandler(ts_ThemeChanged);
            LayoutRoot.Background = App.Current.Resources[“BkgBrush”] as SolidColorBrush;
        }
The UserControl(MainContent.xaml) has the applciation specific logic, nothing special w.r.t themes, except for the fact that the current selection is maintained in the listbox by saving the selected item in IsolatedStorageSettings.ApplicationSettings.

ThemeSelection.xaml is the UserControl where we make the ThemeSelection which has logic to raise the event, when the theme changes we reload. The contentControls clear the App.Resources and load the styles from IsolatedStorageSettings.ApplicationSettings
  private void SetTheme(string s)
        {
            App.Current.Resources.Clear();
            List<Theme> themeSettings = new List<Theme>();          
            themeSettings = IsolatedStorageSettings.ApplicationSettings[s] as List<Theme>;
          
            foreach (Theme t in themeSettings)
                App.Current.Resources.Add(t.Key, XamlReader.Load(t.Value));  
        }

It doesnt have any optimizations or error checking, so the initial load(bit slow) and time for changing themes could be reduced by some variations

you can download the source here

please leave a comment if you have any variations that you come up with.

7 thoughts on “Dynamic Styles

    1. DataGrid has changed a lot since this post. so this will not work as some of the types have changed. I dont have sl2 installed

Leave a comment