Bitesized tidbits for building Modern (Metro) apps.
When Windows Phone first came out, setting custom themes was easy. Take a copy of ThemeResources from ‘c:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Design\’ and swap the colours out with the theme colours you wanted. This changed when the 7.1 SDK came out that meant the default colours weren’t overridden. So what then? Retemplate all the controls to use the colours you want? No.
Jeff Wilcox has a great tool called ThemeManager that lets you, with one line of code, set either a light or dark theme. It also lets you change the accent colour used by your app, however, it doesn’t support custom themes. Sorry, didn’t support custom themes. I’ve now forked Jeff’s code and extended the ThemeManager to allow for them.
Download the ThemeManager.cs from GitHub and add it to your project. Add the ThemeResource.xaml with your custom theme changes and add it with Build type Resource. Now, here’s the cool thing, add that xaml as a MergedDictionary in your App.xaml and you can see all those theme changes within Blend, although you don’t have to do this.
Now, to actually set the custom theme, in your App.xaml.cs, in the App constructor, just set ThemeManager.SetCustomTheme(..). This method has two usages, either pass it the URI of the ResourceDictionary or pass it a ResourceDictionary object.
This would be my recommended usage (having put the ResourceDictionary as a MergedDictionary):
// Get the custom theme var rd = App.Current.Resources.MergedDictionaries; // Set custom Theme ThemeManager.SetCustomTheme(rd, Theme.Light);
So you simply pass the ResourceDictionary and a Theme type (Light or Dark). The Light or Dark theme type is there in case you still want particular aspects of the Light or Dark theme (for example, you might still want the AppBar to use the Light/Dark theme). Speaking of the AppBar, want to change that, too? No problem, just make sure your theme xaml contains a PhoneChromeColor resource.
NOTE: If you take the approach I’ve outlined (putting the ResourceDictionary in the MergedDictionary), the last thing the SetCustomTheme method does is remove it from the MergedDictionary list. The reason for this is that keeping it in there means not all Colors stay set (like the PhoneForegroundColor). I’m not overly sure why this is, but removing it as a MergedDictionary does the job. To this end, don’t include anything in that Dictionary that you might later rely upon, put it in a different one.
Thanks go to Jeff Wilcox for his wonderful ThemeManager and making it open source so it can be tinkered with.