Create re-usable Silverlight 4 Application Theme libraries

by Fred 21. February 2011 12:52

A while back, the UX design team for Silverlight has released helpful application themes for Silverlight 4.

The themes come together with VSIX files (Visual Studio extension installers) which are actually nothing else than zip files that use the Open Packaging Convetion. Visual Studio 2010 will recognize the VISX extension and install the contents. After the installation, you'll find new templates in your Visual Studio, so you can say File/New/Project...Silverlight Navigation with Cosmopolitan Theme.


This is pretty cool. But what if you want to change the application theme at run-time? This post explains one method of achieving this by using the Silverlight Toolkit approach.

In the above solution, add a new Silverlight class library project named Controls.Theming.Cosmopolitan.

new class library

Move the Assets from the Silverlight application to your library by drag and drop and ensure their build action is set to 'Resource'.
properties

Next, add all necessary references and rename class1.cs to CosmopolitanTheme.cs. Necessary here means there are xml namespaces defined in the theme's resource dictionaries referencing things like the Silverlight Toolkit.
Once installed, you can use NuGet to insert the references. Open Visual Studio, click on Tools/Library Package Manager/Package Manager Console and enter the following instruction:

install-package SilverlightToolkit-All

After adding references, for every reference you add, right click and choose copy local: false. Instead, every reference that the theme depends on should be added to the main project (containing the App.xaml) with copy local: true. This ensures the assemblies are available when the theme needs them. (NOTE: if you work with dynamically loaded modules, i.e. by using MEF, you should add the reference to the theme and its dependent references (such as the Silverlight Toolkit) to the module instead of the main project).

Then, add a new "Silverlight Resource Dictionary" and name it Theme.xaml:

Add new Silverlight Resource Dictionary

Your class library should look like this:


Solution with Theme.xaml

The Theme.xaml is going to be our resource dictionary that merges a bunch of other dictionaries.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary
 Source="/Controls.Theming.Cosmopolitan;component/Assets/CoreStyles.xaml"/>
        <ResourceDictionary
 Source="/Controls.Theming.Cosmopolitan;component/Assets/Styles.xaml"/>
        <ResourceDictionary
 Source="/Controls.Theming.Cosmopolitan;component/Assets/SDKStyles.xaml"/>
        <ResourceDictionary
 Source="/Controls.Theming.Cosmopolitan;component/Assets/ToolkitStyles.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


And here's the implementation for CosmopolitanTheme.cs:

public class CosmopolitanTheme : Theme
{
  private static Uri ThemeResourceUri = 
  new Uri("/Controls.Theming.Cosmopolitan;component/Theme.xaml"UriKind.Relative);

  public
 CosmopolitanTheme() : base(ThemeResourceUri)
  {
  }

  public
 static bool GetIsApplicationTheme(Application app)
  {
    return GetApplicationThemeUri(app) == ThemeResourceUri;
  }

  public static void SetIsApplicationTheme(Application app, bool value)
  {
    SetApplicationThemeUri(app, ThemeResourceUri);
  }
}


That's it. Now, the new theming library is ready for use. If you do that for the other themes as well, you can easily switch the theme at run-time.

 private void Application_Startup(object sender, StartupEventArgs e)
 {
     this.RootVisual = new MainPage();
    CosmopolitanTheme.SetIsApplicationTheme(Application.Current, true);
 }

If you work with Style Mapping, as described here, you can add your Styleguide.xaml resource dictionary as well and map Brushes or Fonts to match the guidelines.

Pingbacks and trackbacks (1)+

Comments are closed