【问题标题】:XAML: How can I change the source of a specific ResourceDictionaryXAML:如何更改特定 ResourceDictionary 的来源
【发布时间】:2017-08-10 03:21:42
【问题描述】:
<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>

如何根据ResourceDictionaryx:Name/x:Uid更改ResourceDictionary.MergedDictionaries内特定ResourceDictionary的来源?

谢谢。

【问题讨论】:

    标签: c# wpf xaml uwp-xaml


    【解决方案1】:

    我认为您无法根据 x:Namex:Uid 做到这一点。 ResourceDictionary 没有为这些标记属性定义映射。例如,UIElement 被标记为UidPropertyAttribute("Uid"),因此UIElement 被标记为x:Uid 属性将具有该值作为Uid 属性。与x:Name 相同的故事。但是ResourceDictionary 没有定义这样的映射,因此这些属性在 xaml 被解析和编译后实际上会丢失。

    现在,你能做些什么呢?想到的一种选择是使用您自己的附加属性为资源字典分配标识符。不幸的是,ResourceDictionary 不继承自 DependencyObject,因此我们不能在其上使用附加属性。

    但是,我们可以通过一种 hack 来滥用附加属性语法并仍然达到目标。让我们像这样定义假的附加属性:

    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];
        }
    }
    

    请注意,此定义不同于通常的附加属性。首先,根本没有附属物。其次,GetNameSetName 两种方法不接受DependencyObject(就像与附加属性相关的方法一样),但ResourceDictionary。但是,因为我们有 GetNameSetName 方法 - 我们可以使用附加属性语法,如下所示:

    <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");
    

    【讨论】:

    • 这是我第一次处理 XAML 资源字典,所以我一无所知。不管怎样,谢谢你的帮助!!
    猜你喜欢
    • 2011-03-10
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多