Overriding ThemeResources in Windows 8.1 Apps
Windows 8.1 offers a new markup extension called ThemeResource, this allows for dynamic theming of your app at runtime. There is also a new RequestedTheme property on FrameworkElement, which allows for retargeting specific islands of content. I was working on a sample today and wanted to write a short post to show how to put this all together with the combination of ThemeDictionaries to create a dynamic app.
When you create a new Windows 8.1 app it behooves you use the built-in brushes and styles. This keeps your app consistent with the Windows experience, and also manages cases where users change their underlying system preferences for things like accessibility. Microsoft provides a reference of the XAML theme resources. To use them in Windows 8 you would just use a StaticResource.
While StaticResource still works, with Windows 8.1, you can use the new ThemeResource markup extension for these references.
This allows the resources to be updated dynamically whenever changes to the theme occur, previously this required an application restart. With the dynamic themes comes a broader reach for theme changing. To allow this, Microsoft added a RequestedTheme property to the FrameworkElement object. This allows you to change themes within the context of any element, even nested.
You can also change these values at runtime in code.
DarkContainer.RequestedTheme = ElementTheme.Dark;
Overrides with ThemeDictionaries
You can override any of these existing styles by specifying a ResourceDictionary as part of the ThemeDictionaries. Each dictionary must specify a key with one of the following names:
The ThemeDictionaries documentation provides all the rules, but the HighContrast key is the default for all high contrast options and the Default key is the fallback when a theme name that cannot be located. Inside the dictionary you can specify any resource override from the full list of theme resource keys.
There is one caveat that I notice in my samples, if you specify an ApplicationPageBackgroundThemeBrush, it’s best to specify the value for all themes, in my case Dark and Light. Until I made this change the Light theme wasn’t using the default white background brush I was looking for. This only seems to be an issue with the page background key, but this code fixed it