Practical support for custom light/dark theme resources on Windows Phone 7
Windows Phone 7's dark/light themes, which allow the user to choose between white-on-black or black-on-white, expose default resource keys for your application to consume. However, since this support doesn't extend to declaring your own light/dark resources, I thought I'd look into a practical solution.
I had a few requirements for the implementation:
- It not should require user code to select between specific resources
- It should support standard resource dictionary files and not require specific naming
- It should not have a runtime performance penalty
- It should work in the Visual Studio "cider" designer
- It should work in Expression Blend
The result is a solution that manages 4 (or 4.5, depending on how you look at it) of those 5, and involves a subclassed ResourceDictionary
To test it out, I will create a page that contains an Image
wrapped in a Border
with the intention of using resources for the ImageSource and BorderBrush, respectively:
(Notice that it's still using StaticResource
)
Next, I created two resource dictionaries in /Resources/Light.xaml
and /Resources/Dark.xaml
, which looked like this:
NOTE: ThemeManagement is the name of the project
Finally, I added the custom resource dictionary to the App.xaml
:
NOTE: ThemeManagement is the name of the project
Now we can take it for a test toast:
- Run the app
- Push the start button on the phone/emulator
- Go to Settings and change the theme to light
- Push Back a few times until you're in the app again
UPDATE: The above test will not work in Mango due to a unfortunate side effect of multitasking. The correct theme will be applied if the application is relaunched from Start.
Dark Theme | Light Theme |
We can also confirm that it works in Cider by switching to the design view:
However, since Cider cannot change themes, we can only see the dark theme.
Limitations
Unfortunately, this solution does not work in Expression Blend. For some reason, Blend parses the Resource BAML (compiled XAML) itself and manually supports Source
and MergedDictionary
attributes. Because of this, the custom ResourceDictionary code never runs and we Blend can't find the resources and you'll receive a warning when the project is opened.
The workaround is to select a theme file for design time resources (you can do so from the Blend warning dialog). I recommend choosing Light, since Cider forces us to use Dark. It is unfortunate that both themes can't be supported, though, as Blend is the one environment that supports swapping between them on the fly.