I’m trying to develop a way of switching Windows Phone 7 application style depending on a setting.
The styles look like this:
- core styles are separated and defined in WP7Style_Dark.xaml and WP7Style_Light.xaml
- the rest of the styles are declared in Styles.xaml
I use the following code to hook up the themes in App.xaml.cs:
var dictionaries = Resources.MergedDictionaries;
dictionaries.Clear();
string source = String.Format("/CommonUI;component/Resources/{0}.xaml", value == AppStyleSet.Light ? "WP7Style_Light" : "WP7Style_Dark");
//base styles
var themeStyles = new ResourceDictionary {Source = new Uri(source, UriKind.Relative)};
dictionaries.Add(themeStyles);
var generalStyles = new ResourceDictionary();
generalStyles.Source = new Uri("/CommonUI;component/Resources/Styles.xaml",UriKind.Relative);
dictionaries.Add(generalStyles);
When executing, setting generalStyles.Source throws an exception (which is a System.Exception stating ‘Unspecified error’). I’ve discovered the exception goes away if I empty the Styles.xaml, but this is not a solution, of course.
What should I do?
Update 2: screw the stack trace, here’s the problem narrowed down:
The theme styles define theme colors.
The general styles keep loading fine until they meet a binding, like this one
... <Setter Property="Color" Value="{StaticResource HighlightColor}" />
So, the StaticResource fails to be resolved and throws the exception. Can this be avoided somehow?
The problem I’ve found with this approach is that there seems to be some asynchronicity about how the resource dictionary loads itself from the URL in the
Sourceproperty. Hence when one dictionary uses{StaticResource key}wherekeyis in a previous dictionary it can fail.One solution solution would be to extract the Xaml using
Application.GetResourceStreamandStreamReader. Then to useXamlReaderto construct theResourceDictionary. That way you can be sure that dependant dictionaries can find static resources they need.Note you would need to ensure you have added each dictionary where so that it is part of the
Application.Resourcestree before loading additional dependant dictionaries.