<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>
如何根据ResourceDictionary
ResourceDictionary.MergedDictionaries
/ ResourceDictionary
更改x:Name
内的x:Uid
来源?
感谢。
答案 0 :(得分:3)
我认为你不能基于x:Name
或x:Uid
来做到这一点。 ResourceDictionary
未定义这些标记属性的映射。例如,UIElement
标有UidPropertyAttribute("Uid")
,因此标有UIElement
属性的x:Uid
将该值作为Uid
属性提供。与x:Name
相同的故事。但是ResourceDictionary
没有定义这样的映射,因此在解析和编译xaml之后这些属性实际上会丢失。
现在,您可以做什么呢?想到的一个选项是使用您自己的附加属性为资源字典分配标识符。很遗憾,ResourceDictionary
不会继承DependencyObject
,因此我们无法在其上使用附加属性。
然而,有一个黑客可以滥用附加属性语法并仍然达到目标。让我们像这样定义伪附加属性:
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];
}
}
请注意,此定义与通常的附加属性不同。首先,根本没有附属物。其次,两个方法GetName
和SetName
不接受DependencyObject
(与附加属性相关的方法一样),但ResourceDictionary
。但是,因为我们有GetName
和SetName
方法 - 我们可以使用附加属性语法,如下所示:
<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>
即使目标对象(ResourceDictionary
)不是依赖对象,并且该属性根本不是附加属性。
现在可以轻松修改目标字典的来源:
var dict = Application.Current.Resources.MergedDictionaries.First(c => ResourceDictionaryExtensions.GetName(c) == "Accents");
dict.Source = new Uri("path to the new dictionary");