I do not think you can do this based on x:Name or x:Uid . ResourceDictionary does not define mappings for these markup properties. For example, a UIElement labeled UidPropertyAttribute("Uid") , and therefore a UIElement marked with an x:Uid attribute will have this value, available as a Uid property. Same story with x:Name . But ResourceDictionary does not define such mappings, and therefore these properties are effectively lost after parsing and compiling xaml.
Now, what can you do instead? One option that comes to mind is to use your own attached property to set the resource dictionary as an identifier. Unfortunately, a ResourceDictionary does not inherit from DependencyObject , so we cannot use attached properties on it.
However, there is one hack with which we can abuse the syntax of the attached property and still achieve the goal. Let me define a fake attached property like this:
public static class ResourceDictionaryExtensions { private static readonly Dictionary<ResourceDictionary, string> _mapping = new Dictionary<ResourceDictionary, string>(); public static void SetName(ResourceDictionary element, string value) { _mapping[element] = value; } public static string GetName(ResourceDictionary element) { if (!_mapping.ContainsKey(element)) return null; return _mapping[element]; } }
Note that this definition is different from the usual attached property. Firstly, there is no property attached. Secondly, the two methods GetName and SetName do not accept DependencyObject (for example, methods associated with attached properties), but ResourceDictionary . However, since we have the GetName and SetName , we can use the syntax of the attached property, for example:
<Application.Resources> <ResourceDictionary x:Name="ThemeDictionary"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/AppStyles;component/Resources/Icons.xaml"/> <ResourceDictionary Source="pack://application:,,,/AppStyles;component/Resources/IconsNonShared.xaml"/> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" /> <ResourceDictionary local:ResourceDictionaryExtensions.Name="Accents" Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" /> <ResourceDictionary local:ResourceDictionaryExtensions.Name="BaseTheme" Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
Although the target ( ResourceDictionary ) is not a dependency object, and this property is not attached at all.
Now itโs easy to change the source of the target dictionary:
var dict = Application.Current.Resources.MergedDictionaries.First(c => ResourceDictionaryExtensions.GetName(c) == "Accents"); dict.Source = new Uri("path to the new dictionary");