Home > Silverlight > Dynamic Styles

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.

About these ads
Categories: Silverlight Tags:
  1. guest
    September 5, 2008 at 6:04 am

    great work

  2. September 8, 2008 at 9:18 am

    I was looking at this http://www.nikhilk.net/Silverlight-Themes.aspx. Probably what it does internally is the same as you have mentioned here.

    Thanks for the details.

  3. October 28, 2008 at 2:01 am

    hi, it does not work in sl 2.0 RTM, it throw Value of local:DataGridColumnHeader of Property TargetType invalid, [Line: 1 Position: 413]

  4. September 9, 2009 at 3:34 pm

    local:DataGridColumnHeader of Property TargetType invalid, [Line: 1 Position: 413]

    getting this error too, SL2

    • lee
      September 9, 2009 at 3:57 pm

      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

  5. October 12, 2011 at 2:24 pm

    I’ve been looking so many places for thsi information.

  1. July 25, 2008 at 2:05 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: