Universal Windows 8.1 Store Project here.
I need to programmatically get a resource from merged dictionaries of an application given a resource name.
I came up with a utility method which gets me what I want, but looks rather ugly to me:
public static async Task<T> GetAppResource<T>(string key) where T:class
{
T resource = default(T);
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
()=>{
foreach (var d in Application.Current.Resources.MergedDictionaries) {
foreach (var pair in d) {
if (pair.Key.ToString() == key && pair.Value is T) {
resource = pair.Value as T;
goto End;
}
}
}
End:;
}
);
return resource;
}
Is there a better way of doing this?
The dictionaries are declared as follows:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..." />
<ResourceDictionary Source="..." />
...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Actually, I'm programmatically opening flyouts declared in the merged dictionaries.
The dictionaries added to a ResourceDictionary
via the MergedDictionaries
property effectively become a part of the ResourceDictionary
to which they are added. Retrieving a value from the top-level ResourceDictionary
will involve searching for the value's key in the main dictionary, and if not found, traversing the MergedDictionaries
to search for the key.
Thus, resources added via MergedDictionaries
can be retrieved pretty much as though they are just contained in the top-level dictionary. The main difference being that duplicate keys are allowed in the merged dictionaries, with the value for a given key being retrieved from the last merged dictionary in which it's found, if not found in the top-level dictionary.
So you can call TryGetValue()
on your top-level dictionary, use the indexer syntax (e.g. Application.Current.Resources["someKey"]
), or even use an appropriate FindResource()
call (i.e. depending on whether the context is an Application
object or FrameworkElement
object). The resource will be retrieved as if it were in the top-level dictionary itself.
I hope the above adequately elaborates on the documentation. The above is implied to some extent by the documentation in MSDN (e.g. Merged Resource Dictionaries), but they never really come right out and say so explicitly. :( The documentation focuses more on how to create merged dictionaries, rather than on how to actually use them once created.