<Application x:Class="CDesign.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CDesign"
StartupUri="MainWindow.xaml">
<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"/>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<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" />
<!-- Accent and AppTheme setting -->
<ResourceDictionary x:Uid="Accents" x:Name="Accents" Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary x:Uid="BaseTheme" x:Name="BaseTheme" Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
How can I change the source of a specific ResourceDictionary
inside ResourceDictionary.MergedDictionaries
based on the ResourceDictionary
's x:Name
/x:Uid
?
Thanks.
I don't think you can do that based on x:Name
or x:Uid
. ResourceDictionary
does not define mappings for those markup properties. For example, UIElement
is marked with UidPropertyAttribute("Uid")
and so UIElement
marked with x:Uid
attribute will have that value available as Uid
property. Same story with x:Name
. But ResourceDictionary
does not define such mappings, and so those properties are effectively lost after xaml is parsed and compiled.
Now, what you can do instead? One option that comes to mind is to use your own attached property to assign resource dictionary an identifier. Unfortunately, ResourceDictionary
does not inherit from DependencyObject
, and so we cannot use attached properties on it.
However, there is one hack with which we can abuse attached property syntax and still reach the goal. Let's define 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 usual attached property. First, there is no attached property at all. Second, two methods GetName
and SetName
do not accept DependencyObject
(like methods associated with attached properties do), but ResourceDictionary
. However, because we have GetName
and SetName
methods - we can use attached property syntax, like this:
<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"/>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<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" />
<!-- Accent and AppTheme setting -->
<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>
Even though target object (ResourceDictionary
) is not dependency object, and that property is not attached property at all.
Now it's easy to modify source of target dictionary:
var dict = Application.Current.Resources.MergedDictionaries.First(c => ResourceDictionaryExtensions.GetName(c) == "Accents");
dict.Source = new Uri("path to the new dictionary");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With