Поделиться через


Новые возможности WPF для .NET 9

В этой статье описаны новые возможности Windows Presentation Foundation (WPF) для .NET 9. Основной областью фокуса для WPF в этом году было улучшение визуальных возможностей WPF и предоставление новой темы на основе принципов проектирования Fluent для Windows 11.

Вы можете предварительно просмотреть новую тему, скачав приложение коллекции WPF из Microsoft Store.

Тема Fluent

Новая тема включена в WPF, которая обеспечивает новую, современную эстетику Windows 11 для приложений WPF. Он включает встроенные светлые и темные режимы, а также поддержку цвета системного акцента.

  • Тема 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 теме только в самом окне.

Режим темы

В WPF добавлен новый API стилей, который предоставляется через ThemeMode свойство. Используя это свойство, вы можете применить стиль Fluent без необходимости ссылаться на словарь ресурсов стилей напрямую.

Доступные значения:

  • Light— применяет светлую тему Fluent.
  • Dark— применяет темную тему Fluent.
  • System— применяет светлую или темную тему Fluent на основе текущего параметра Windows пользователя.
  • 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, что позволяет настроить тему 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.Color, System.Windows.Media.SolidColorBrushили System.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 или без нее.

При создании пользовательского интерфейса, использующего цвет акцента, заключите ключ ресурса в динамический ресурс. Когда пользователь изменяет цвет акцента во время открытия приложения, цвет обновляется автоматически в приложении. Например, вот TextBlock цвет переднего плана, заданный для выбранного цвета акцента пользователя:

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

Поддержка лигатуры на основе дефиса

WPF никогда не поддерживает лигатуры на основе дефиса в элементах управления пользовательского интерфейса, таких как TextBlock. Этот давний вопрос сообщества был добавлен в .NET 9.

Вот изображение лигатур, которые не применяются к глифам в .NET 8:

Снимок экрана: простое приложение WPF с текстовым блоком, показывающее, как глифы не объединяются в лигатуры с .NET 8.

И теперь тот же текст, что и отрисованный в .NET 9:

Снимок экрана простого приложения WPF с текстовым блоком, показывающим, как глифы объединяются в лигатуры с .NET 9.

BinaryFormatter больше не поддерживается

BinaryFormatter считается небезопасным, поскольку он уязвим для атак десериализации, что может привести к отказу в обслуживании (DoS), раскрытию информации или удаленному выполнению кода. Она была реализована до того, как уязвимости десериализации были хорошо поняты, и его дизайн не соответствует современным рекомендациям по обеспечению безопасности.

Начиная с .NET 9, его реализация была удалена, чтобы предотвратить эти риски безопасности. Когда используется BinaryFormatter, выбрасывается исключение PlatformNotSupportedException.

WPF используется BinaryFormatter во многих сценариях, например при сериализации данных для операций буфера обмена и перетаскивания. В настоящее время WPF продолжает использовать более безопасное подмножество BinaryFormatter для обработки конкретных вариантов использования с известным набором типов.

Дополнительные сведения см. в руководстве по BinaryFormatterмиграции WPF для BinaryFormatter.