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

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

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

Fluent 主题

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

  • 浅色模式下的 Fluent 主题:

    WPF 库应用的屏幕截图,演示浅色模式下的 Fluent 主题。

  • 深色模式下的 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 仅窗口本身的主题。

ThemeMode

已将新的样式 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访问这些项:

Color 颜色资源密钥 Brush 画笔资源键
口音 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 将引发异常。

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

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