适用于 .NET 9 的 WPF 中的新增功能

本文介绍适用于 .NET 9 的 Windows Presentation Foundation (WPF)中的新增功能。 今年 WPF 的主要重点领域是改进 WPF 的视觉功能,并根据 Windows 11 的 Fluent 设计原则提供新主题。

可以通过从 Microsoft 应用商店下载 WPF 库应用来预览新主题。

Fluent 主题

WPF 附带了一个新主题,它为 WPF 应用提供全新的现代 Windows 11 美学。 它包括集成的浅色和深色模式,以及系统主题色支持。

  • 浅色模式下的 Fluent 主题:

    WPF 画廊应用的屏幕截图,演示浅色模式下的流畅主题。

  • 深色模式下的 Fluent 主题:

    WPF 画廊应用的屏幕截图,展示了深色模式下的 Fluent 主题

应用主题

可以通过两种方式应用 Fluent 主题,设置 ThemeMode 属性或引用 Fluent 主题资源字典。 有关主题模式设置的详细信息,请参阅 ThemeMode

Fluent 主题资源字典在以下包 URI 中可用: /PresentationFramework.Fluent;component/Themes/Fluent.xaml 若要在应用程序级别应用资源,请将资源加载到应用的资源中:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

还可以将资源字典应用于 Window,以仅将主题应用到窗口本身。

主题模式

已将新的样式 API 添加到 WPF,该 API 通过 ThemeMode 属性公开。 通过使用此属性,可以应用 Fluent 样式,而无需直接引用样式设置资源字典。

可用值为:

  • Light— 应用浅色 Fluent 主题。
  • Dark- 应用深色 Fluent 主题。
  • System- 根据用户的当前 Windows 设置应用浅色或深色 Fluent 主题。
  • None— (默认值) 使用 Aero2 主题。

若要为整个应用程序应用主题模式,请在类型上ThemeMode设置Application属性。 若要将其应用于单个窗口,请在ThemeMode类型上设置Window

例如,根据 Windows 设置的当前浅色或深色主题设置整个应用程序样式:

<Application x:Class="MyWpfProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyWpfProject"
             StartupUri="MainWindow.xaml"
             ThemeMode="System">

强制应用浅色主题的一个示例,而不考虑 Windows 本身的主题设置:

<Window x:Class="MyWpfProject.LightWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyWpfProject"
        Title="LightWindow" Height="450" Width="800"
        ThemeMode="Light">

如果在应用程序级别设置 ThemeMode 为不是 None 的任何值,None 就不能在窗口级别应用。

ThemeMode 旨在遵循由 Fluent Dictionary 确定的设置,以便您可以定制 Fluent 主题。

在代码中配置

支持更改代码中的设置 ThemeMode 目前是一项实验性功能。 访问 ThemeMode 代码中的属性将生成错误 WPF0001,从而阻止访问 API。 抑制访问 API 时的错误。

警告

此 API 是实验性的,可能会更改。

首先,将以下 PropertyGroup 元素添加到项目文件中以抑制错误。

<PropertyGroup>
    <NoWarn>$(NoWarn);WPF0001</NoWarn>
</PropertyGroup>

小窍门

可以使用 #pragma warning disable WPF0001 指令来在错误发生的位置抑制错误,而不是对整个项目禁用该错误。

接下来,在应用程序级别或窗口级别设置 ThemeMode 属性:

// Set light mode at the application-level
Application.Current.ThemeMode = ThemeMode.Light;

// Set dark mode on the current window
this.ThemeMode = ThemeMode.Dark;

支持 Windows 主题色

Windows 10 引入了用户选择的主题色,用于提供个人触摸或调用特定视觉元素。 WPF 现在支持用户选择的主题色。

可用的颜色选项包括System.Windows.Media.ColorSystem.Windows.Media.SolidColorBrushSystem.Windows.ResourceKey。 除了颜色本身,还可以使用强调色的浅色和深色色调。 可以通过 System.Windows.SystemColors 访问这些项:

颜色 颜色资源密钥 刷子 画笔资源键
口音 AccentColor AccentColorKey AccentColorBrush AccentColorBrushKey
浅色 1 AccentColorLight1 AccentColorLight1Key AccentColorLight1Brush AccentColorLight1BrushKey
浅色 2 AccentColorLight2 AccentColorLight2Key AccentColorLight2Brush AccentColorLight2BrushKey
浅色 3 AccentColorLight3 AccentColorLight3Key AccentColorLight3Brush AccentColorLight3BrushKey
深色 1 AccentColorDark1 AccentColorDark1Key AccentColorDark1Brush AccentColorDark1BrushKey
深色 2 AccentColorDark2 AccentColorDark2Key AccentColorDark2Brush AccentColorDark2BrushKey
深色 3 AccentColorDark3 AccentColorDark3Key AccentColorDark3Brush AccentColorDark3BrushKey

重要

辅色可以在有或没有 Fluent 主题的情况下使用。

创建使用主题色的 UI 时,请将资源键包装在动态资源中。 当用户在打开应用时更改主题色时,该颜色会在应用中自动更新。 例如,下面是一个 TextBlock,其前景色设置为用户选择的强调色:

<TextBlock Text="First Name:"
           Foreground="{DynamicResource {x:Static SystemColors.AccentColorBrushKey}}" />

基于连字符的连字功能支持

WPF 从未在 UI 控件(如 TextBlock)中支持基于连字符的连字。 这个长期存在的社区要求已在 .NET 9 中添加。

这是未应用于 .NET 8 字形的连字的图像。

这是一个简单 WPF 应用程序的屏幕截图,显示了在 .NET 8 中字形未合成为连字的文本块。

现在,在 .NET 9 中呈现的文本如下:

一张简单 WPF 应用的截图,其中一个文本块显示了在 .NET 9 中字形如何被组合成连字。

不再支持 BinaryFormatter

BinaryFormatter 被视为不安全,因为它容易受到反序列化攻击,这可能导致拒绝服务(DoS)、信息泄露或远程代码执行。 它在反序列化漏洞被充分理解之前实现,其设计不遵循现代安全最佳做法。

从 .NET 9 开始,其实现已被删除,以防止这些安全风险。 使用时 BinaryFormatterPlatformNotSupportedException 将引发异常。

WPF在许多场景中使用BinaryFormatter,例如在剪贴板和拖放操作的数据序列化时。 在内部,WPF 继续使用更安全的 BinaryFormatter 子集来处理具有已知类型集的特定用例。

有关详细信息 BinaryFormatter,请参阅 BinaryFormatter 的 WPF 迁移指南