对比度主题

对比主题使用少量颜色(对比度至少为 7:1)来帮助使 UI 中的元素更易于查看、减少眼睛疲劳、提高文本可读性并适应用户偏好。

注意

不要将对比度主题与浅色和深色主题混淆,该主题支持更大的调色板,不一定增加对比度或使事情更容易看到。 有关浅色和深色主题的更多信息,请参阅颜色

若要查看应用使用对比度主题的行为方式,请通过设置>辅助功能>对比度主题页面启用和自定义它们。

提示

还可以按左 Alt 键 + Shift 键 + Print screen(某些键盘上是 PrtScn)快速打开或关闭对比度主题。 如果之前没有选择过主题,则默认使用 Aquatic 主题(如下图所示)。

Calculator shown in Light theme and Aquatic contrast theme.

将 HighContrastAdjustment 设置为 None

默认情况下,Windows 应用开启 HighContrastAdjustment。 这会将所有文本颜色设置为白色,并以纯黑色为背景突出显示,确保与所有背景有足够的对比度。 如果正确使用了画笔,应关闭此设置。

检测高对比度

可以通过 AccessibilitySettings 类以编程方式检查当前主题是否是对比度主题(你必须从应用已初始化且已显示内容的范围调用 AccessibilitySettings 构造函数)。

创建主题字典

ResourceDictionary.ThemeDictionaries 对象可以通过为 Default(深色)、Light 和 HighContrast 对比度主题指定画笔来指示不同于系统定义颜色的主题颜色。

提示

对比度主题是指一般的特征,而 HighContrast 是指被引用的特定字典。

  1. 在 App.xaml 中,使用 Default 和 HighContrastResourceDictionary 创建一个 ThemeDictionaries 集合(此示例不需要 LightResourceDictionary)。

  2. 在 Default 中,创建需要的 Brush 类型,通常为 SolidColorBrush。 为其提供一个与其预期用途相对应的 x:Key 名称(引用现有系统画笔的 StaticResource 也是合适的)。

  3. 在 HighContrast ResourceDictionary(如下代码片段所示)中,指定适当的 SystemColor 画笔。 有关为 SystemColor 画笔选择一种动态系统 HighContrast 颜色的详细信息,请参阅对比度颜色

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <!-- Default is a fallback if a more precise theme isn't called
                out below -->
                <ResourceDictionary x:Key="Default">
                    <SolidColorBrush x:Key="BrandedPageBackgroundBrush" Color="#E6E6E6" />
                </ResourceDictionary>
    
                <!-- Optional, Light is used in light theme.
                If included, Default will be used for Dark theme -->
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="BrandedPageBackgroundBrush" Color="#E6E6E6" />
                </ResourceDictionary>
    
                <!-- HighContrast is used in all high contrast themes -->
                <ResourceDictionary x:Key="HighContrast">
                    <SolidColorBrush x:Key="BrandedPageBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}" />
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Application.Resources>
    

对比度颜色

在下图>) 中显示的设置“轻松访问>对比度”主题 (页上,用户可以从四个默认对比度主题中进行选择:水生、沙漠、黄昏和夜空。

Contrast theme settings.

用户选择一个选项后,可以选择立即应用,也可以编辑主题。 下图显示了“水族”对比主题的编辑主题对话框。

Settings - Edit theme dialog for the **Aquatic** contrast theme.

下表显示对比度主题颜色及其建议搭配。 每一个 SystemColor 资源都是一个变量,可在用户切换对比度主题时自动更新颜色。

颜色样本 说明
SystemColorWindowColor
页面、窗格、弹出窗口和窗口的背景。

与 SystemColorWindowTextColor 搭配
SystemColorWindowTextColor
标题、正文复制、列表、占位符文本、应用和窗口边框,任何无法与之交互的 UI。

SystemColorWindowColor 配对
SystemColorHotlightColor
链接。

SystemColorWindowColor 配对
SystemColorGrayTextColor
) UI 禁用非活动 (。

SystemColorWindowColor 配对
SystemColorHighlightTextColor
所选文本或 UI 的前景色、与 (悬停交互、按下) 或正在进行中。

SystemColorHighlightColor 配对
SystemColorHighlightColor
所选 UI 的背景色或主题色、与 (悬停交互、按下) 或正在进行中。

SystemColorHighlightTextColor 配对
SystemColorButtonTextColor
按钮和任何可以与之交互的 UI 的前景色。

SystemColorButtonFaceColor 配对
SystemColorButtonFaceColor
按钮和任何可以与之交互的 UI 的背景色。

SystemColorButtonTextColor 配对

下表显示了在设置为 SystemColorWindowColor 的背景上使用颜色时的显示方式。

示例
A window with text using the window text color. SystemColorWindowTextColor
A window with hyperlink text using the hot light color. SystemColorHotlightColor
A window with inactive text using the gray text color. SystemColorGrayTextColor
A window with text using the highlight text color on the highlight color. SystemColorHighlightTextColor + SystemColorHighlightColor
A window with a button using the 3d face color and button text using the button text color. SystemColorButtonTextColor + SystemColorButtonFaceColor

在下面的代码片段中,我们展示了如何为 BrandedPageBackgroundBrush 选择资源。 SystemColorWindowColor 是一个不错的选择,因为BrandedPageBackgroundBrush 表明它将用于背景。

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <!-- Default is a fallback if a more precise theme isn't called
            out below -->
            <ResourceDictionary x:Key="Default">
                <SolidColorBrush x:Key="BrandedPageBackgroundBrush" Color="#E6E6E6" />
            </ResourceDictionary>

            <!-- Optional, Light is used in light theme.
            If included, Default will be used for Dark theme -->
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="BrandedPageBackgroundBrush" Color="#E6E6E6" />
            </ResourceDictionary>

            <!-- HighContrast is used in all high contrast themes -->
            <ResourceDictionary x:Key="HighContrast">
                <SolidColorBrush x:Key="BrandedPageBackgroundBrush" Color="{ThemeResource SystemColorWindowColor}" />
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Application.Resources>

然后将资源分配给元素的背景。

<Grid Background="{ThemeResource BrandedPageBackgroundBrush}">

在前面的示例中使用了 {ThemeResource} 两次,一次引用 SystemColorWindowColor ,并再次引用 BrandedPageBackgroundBrush。 两次都需要应用在运行时搭配正确主题。 此时适合测试应用功能。 当你切换到高对比度主题时,网格背景将自动更新。 当在不同高对比度主题之间切换时,它的背景也随之更新。

注意

WinUI 2.6 和更高版本

有八个高对比度系统画笔可用于通过 ResourceKey 进行引用(请参阅以下 SystemColorWindowTextColorBrush 示例)。

<StaticResource x:Key="MyControlBackground" ResourceKey="SystemColorWindowTextColorBrush" />

画笔名称与前面提到的八种系统颜色之一完全匹配(附加“Brush”)。 出于性能原因,我们建议使用 StaticResource 而不是本地 SolidColorBrush。

最佳实践

以下是一些关于在你的 Windows 应用中自定义对比主题颜色的建议。

  • 在你的应用运行时测试所有四个高对比度主题。
  • 保持一致。
  • 确保在你的应用中将 HighContrastAdjustment 设置为 None(默认情况下已开启)。 请参阅将 HighContrastAdjustment 设置为 None
  • 不要对 HighContrast 主题中的颜色进行硬编码。 请改用 SystemColorColorColorBrush 资源。 有关更多详细信息,请参阅硬编码颜色
  • 不要混合不兼容的背景/前景对
  • 不要单纯为了美观而选择色彩资源。 请记住,颜色会随主题而改变。
  • 不要对辅助性或提示性文本使用 SystemColorGrayTextColor。 这仅适用于禁用的内容。
  • 不要使用 SystemColorHotlightColor 和相应的画笔,因为两者都是为超链接保留的。

提示

查看 WinUI 库应用通常很有帮助,了解常见控件如何使用 SystemColor 画笔。 如果已安装,请单击以下链接打开它们: WinUI 3 库WinUI 2 库

如果未安装它们,可以从Microsoft Store下载 WinUI 3 库WinUI 2 库

还可以从GitHub获取源代码 (使用 WinUI 3 的主分支和 WinUI 2) 的 winui2 分支。

硬编码颜色

平台控件提供了对对比主题的内置支持,但在自定义应用程序 UI 时应该慎重。 当元素的颜色被硬编码或使用不正确的 SystemColor 资源时,会出现两个最常见的问题。

在下面的代码片段中,我们展示了一个背景颜色设置为 #E6E6E6(非常浅的灰色)声明的 Grid 元素。 如果你以这种方式对颜色进行硬编码,你还将覆盖所有主题的背景颜色。 例如,如果用户选择“水族”对比度主题,而不是接近黑色背景上的白色文本,则此应用中的文本颜色将变为白色,而背景仍为浅灰色。 文本和背景之间非常低的对比度可能使此应用非常难以使用。

<Grid Background="#E6E6E6">

相反,我们建议使用 {ThemeResource} 标记扩展来引用 ResourceDictionaryThemeDictionaries 集合中的颜色。 这可以根据用户当前的主题自动替换颜色和画笔。

<Grid Background="{ThemeResource BrandedPageBackgroundBrush}">

边框

页面、窗格、弹出窗口和栏应该都使用 SystemColorWindowColor 作为它们的背景。 必要时,请只添加对比度主题边框来保留 UI 中的重要边界。

提示

我们建议对浮出控件和对话框等临时表面使用 2px 边框。

在对比度主题中下,导航窗格和页面共享同一背景色。 为了区分它们,只有对比主题的边框是必不可少的。

A navigation pane separated from the rest of the page.

带有彩色文本的列表项

在对比度主题中,用户将光标悬停在 ListView 中的项目上、按下或选择它们时,它们会将自己的背景设置为 SystemColorHighlightColor。 当列表项的内容无法反转其颜色时,会出现复杂列表项的常见问题,从而使列表项无法阅读。

ListView 的 DataTemplate 中设置 TextBlock.Foreground 时要小心(通常是为了建立视觉层次结构)。 Foreground 属性在 ListViewItem 上设置,并且 DataTemplate 中的 TextBlocks 继承正确的前景色。 设置 Foreground 将打断这种继承关系。

Complex list in Light theme and Aquatic theme (note how the text color is not inverted in HighContrast).

可以通过 ThemeDictionaries 集合中的 Style 有条件地设置 Foreground 来解决此问题。 因为 Foreground 并非由 HighContrast 中的 SecondaryBodyTextBlockStyle 设置,所以颜色将正确反转。

Complex list in Light theme and Aquatic theme (note how the text color is inverted in HighContrast).

以下代码片段(来自应用.xaml 文件)显示了 ListView 数据模板中的示例 ThemeDictionaries 集合。

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Default">
        <Style
            x:Key="SecondaryBodyTextBlockStyle"
            TargetType="TextBlock"
            BasedOn="{StaticResource BodyTextBlockStyle}">
            <Setter Property="Foreground" 
                Value="{StaticResource SystemControlForegroundBaseMediumBrush}" />
        </Style>
    </ResourceDictionary>

    <ResourceDictionary x:Key="Light">
        <Style
            x:Key="SecondaryBodyTextBlockStyle"
            TargetType="TextBlock"
            BasedOn="{StaticResource BodyTextBlockStyle}">
            <Setter Property="Foreground" 
                Value="{StaticResource SystemControlForegroundBaseMediumBrush}" />
        </Style>
    </ResourceDictionary>

    <ResourceDictionary x:Key="HighContrast">
        <!-- The Foreground Setter is omitted in HighContrast -->
        <Style
            x:Key="SecondaryBodyTextBlockStyle"
            TargetType="TextBlock"
            BasedOn="{StaticResource BodyTextBlockStyle}" />
    </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

<!-- Usage in your DataTemplate... -->
<DataTemplate>
    <StackPanel>
        <TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="Double line list item" />

        <!-- Note how ThemeResource is used to reference the Style -->
        <TextBlock Style="{ThemeResource SecondaryBodyTextBlockStyle}" Text="Second line of text" />
    </StackPanel>
</DataTemplate>