Saturday, June 23, 2012

How to Switch Between Dark and Light Theme


The Windows Phone OS has a global Theme setting available for the user to change. This one setting affects every application. The Windows 8 seems to take a different approach (at least in Windows 8 RP): There’s no global theme setting, instead it’s up to the developer to decide if her application uses the dark or the light theme.

Defining the application theme in XAML

Maybe the easies way to define the application theme for the Metro application is to use the App.xaml. The Application-element has aRequestedTheme-attribute which can be set to either Dark or Light.
?
1
2
3
4
5
6
7
<Application
    x:Class="windows8_metro_themes.App"
    xmlns:local="using:windows8_metro_themes"
    xmlns:localData="using:windows8_metro_themes.Data"
    RequestedTheme="Dark">
The App.xaml route works well if the theme is hard coded. But if the user can customize app’s theme, it’s maybe easier to set the theme in code.

Defining the application theme in code

The application theme can be set in the constructor of the App-class using code.
?
1
RequestedTheme = ApplicationTheme.Light;
The application theme cannot be changed when the application is running and trying to set it throws an exception. For example the OnLaunched-method in App.xaml.cs is already too late.
You could read the theme from application’s settings, making the theme configurable. Here’s an example where the current theme is stored in to application’s roaming settings:
?
1
2
3
4
5
6
7
8
9
10
var settings = Windows.Storage.ApplicationData.Current.RoamingSettings;
string currentTheme = null;
if (settings.Values.ContainsKey("currentTheme"))
{
    currentTheme = settings.Values["currentTheme"] as string;
    settings.Values.Remove("currentTheme");
}
settings.Values.Add("currentTheme", currentTheme == "light" ? "dark" : "light");
And here’s App’s constructor where values is read:
?
1
2
3
4
5
6
7
8
9
10
11
12
public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;
    var settings = Windows.Storage.ApplicationData.Current.RoamingSettings;
    if (settings.Values.ContainsKey("currentTheme") && (string) settings.Values["currentTheme"] == "light")
        RequestedTheme = ApplicationTheme.Light;
    else
        RequestedTheme = ApplicationTheme.Dark;
}
Note that the RequestedTheme-attribute in App.xaml seems to override the value set in the App’s constructor.

Defining the application theme for the Visual Studio designer

It’s possible to test both of the themes without running the app, using the Device-dialog.
image
You can switch between the Dark and the Light theme easily. The same dialog has other interesting options too, like the ability to switch the device inside the designer to the portrait mode.

Theme definitions

The XAML of the different themes are available from the following location: C:\Program Files (x86)\Windows Kits\8.0\Include\winrt\xaml\design\themeresources.xaml