UWP / XAML:页面的资源,单独的ResourceDictionary文件或App.xaml中的主题有什么区别?

时间:2016-05-20 14:14:23

标签: xaml uwp uwp-xaml

我有一个只有一个页面的简单UWP应用程序。在尝试覆盖SystemAccentColor时(请参阅this one等其他问题),我发现在3个有效位置的每一个中我都会得到不同的结果来添加代码:

  1. 在页面本身的参考资料部分。 (什么都不做)

  2. 在单独的ResourceDictionary文件中。 (仅部分有效)

  3. 在App.xaml文件中。 (工程)

  4. 这是我单页的Page.Resources,我的自定义样式包含在Dictionary.xaml中:

    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    

    以下是我在3个位置中插入的SystemAccentColor代码,以下称为//代码//:

    <Color x:Key="SystemAccentColor">Red</Color>
    
    <SolidColorBrush x:Key="SystemControlBackgroundAccentBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="SystemControlDisabledAccentBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="SystemControlForegroundAccentBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="SystemControlHighlightAccentBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="SystemControlHighlightAltAccentBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="SystemControlHighlightAltListAccentHighBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.9" />
    <SolidColorBrush x:Key="SystemControlHighlightAltListAccentLowBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.6" />
    <SolidColorBrush x:Key="SystemControlHighlightAltListAccentMediumBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.8" />
    <SolidColorBrush x:Key="SystemControlHighlightListAccentHighBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.9" />
    <SolidColorBrush x:Key="SystemControlHighlightListAccentLowBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.6" />
    <SolidColorBrush x:Key="SystemControlHighlightListAccentMediumBrush" Color="{ThemeResource SystemAccentColor}" Opacity="0.8" />
    <SolidColorBrush x:Key="SystemControlHyperlinkTextBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="ContentDialogBorderThemeBrush" Color="{ThemeResource SystemAccentColor}" />
    <SolidColorBrush x:Key="JumpListDefaultEnabledBackground" Color="{ThemeResource SystemAccentColor}" />
    

    Page

    的参考资料部分

    将//代码//插入Page.Resources什么都不做。

    <ResourceDictionary>
    
        <ResourceDictionary.ThemeDictionaries>
            //THE CODE//
        </ResourceDictionary.ThemeDictionaries>
    
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    
    </ResourceDictionary>
    

    指定这应该适用于Light主题也不会做任何事情。

    <ResourceDictionary>
    
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                //THE CODE//
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    
    </ResourceDictionary>
    

    ResourceDictionary中

    将//代码//插入Dictionary.xaml也不会做任何事情。

    <ResourceDictionary.ThemeDictionaries>
        //THE CODE//
    </ResourceDictionary.ThemeDictionaries>
    

    但是,指定Light / Dark主题会导致应用颜色覆盖,但仅适用于我的自定义样式,这些样式也在Dictionary.xaml中定义。但是,它仅适用于Windows浅色/深色主题匹配的情况。

    <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Light">
            //THE CODE//
        </ResourceDictionary>
    </ResourceDictionary.ThemeDictionaries>
    

    的App.xaml

    在App.xaml中插入//代码//正常工作。

    <Application.Resources>
        <ResourceDictionary>
            //THE CODE//
        </ResourceDictionary>
    </Application.Resources>
    

    编辑:我也可以将Dark / Light主题指定为x:Key,一切都按预期工作。

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    //THE CODE//
            </ResourceDictionary.ThemeDiciontaries>
        </ResourceDictionary>
    </Application.Resources>
    

    总结

    总而言之,这是怎么回事?这显然看起来像某种范围问题,但我在开发人员文档中找不到任何可以解释我在这里看到的行为的内容。

1 个答案:

答案 0 :(得分:0)

其中许多不起作用的原因是ResourceDictionary.ThemeDictionaries期望它的内容是资源字典,并且具有与各个项目相对应的键。如果在其中放置常规资源(例如主题笔刷),则主题资源查找将不知道该怎么做,因此不会占用资源。

如果您在词典中指定了资源,并且还加载了包含该资源的字典,则资源字典将覆盖主题资源字典的值,因此,为什么要混合主题字典并将资源字典加载到合并的字典中,这是为什么通常是个坏主意。

在仅在主题词典“ light”中指定资源的情况下,当apps / pages词典为light theme时,资源查找将拾取该资源。但是,如果页面的主题是深色主题,则它将查找“ dark”字典(在您的情况下该字典不存在),然后在树上向上查找直到找到具有指定资源的深色主题字典。因此,要在所有主题中覆盖该资源,您需要在所有主题词典(亮,暗和默认)中指定该资源。