窗口化功能迁移

本主题包含与窗口管理相关的指南,包括从 UWP 的“ApplicationView”/“CoreWindow”“AppWindow”迁移到 Window 应用 SDK “Microsoft.UI.Windowing.AppWindow”

重要的 API

API 和/或功能差异摘要

Windows 应用 SDK 提供基于 Win32 HWND 模型的 Microsoft.UI.Windowing.AppWindow 类。 该 AppWindow 类是 UWP ApplicationView/CoreWindowAppWindow 的 Windows 应用 SDK 版本。

利用 Windows应用 SDK 窗口化 API 意味着会迁移 UWP 代码以使用 Win32 模型。 有关 Windows 应用 SDK AppWindow 的详细信息,请参阅管理应用窗口

提示

管理应用窗口主题包含一个代码示例,演示如何从 WinUI 3 窗口检索 AppWindow。 在 WinUI 3 应用中,使用该代码模式,以便可以调用本主题其余部分中提到的 AppWindow API。

UWP 与 Windows 应用 SDK 中的窗口类型

在 UWP 应用中,可以使用 ApplicationView/CoreWindowAppWindow 承载窗口内容。 将该代码迁移到 Windows 应用 SDK 所涉及的工作取决于 UWP 应用使用这两种窗口化模型中的哪一种。 如果熟悉 UWP 的Windows.UI.WindowManagement.AppWindow,你可能会看到它与 Microsoft.UI.Windowing.AppWindow 之间的相似之处。

UWP 窗口类型

Windows 应用 SDK 窗口类型

请记住,UWP 与 Win32 之间的窗口化模型差异意味着 UWP API 图面与 Windows 应用 SDK API 图面之间不是直接 1:1 映射。 即使对于的确从 UWP 集成的类和成员名称(在本主题的映射表中进行反映),行为也可能有所不同。

初始屏幕

与 UWP 应用不同,Win32 应用默认情况下在启动时不会显示初始屏幕。 依赖于此功能获得启动体验的 UWP 应用可以选择实现到其第一个应用窗口的自定义转换。

创建、显示、关闭和销毁窗口

Microsoft.UI.Windowing.AppWindow 的生存期与 HWND 的生存期相同;这意味着 AppWindow 对象在窗口创建后立即可用,在窗口关闭时销毁。

创建和显示

AppWindow.Create 使用默认配置创建应用窗口。 只有在未使用 UI 框架的情况下,才需要创建和显示窗口。 如果要将 UWP 应用迁移到与 Win32 兼容的 UI 框架,则仍可以使用窗口化互操作方法从已创建的窗口访问 AppWindow 对象。

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
CoreApplication.CreateNewView

CoreWindow.GetForCurrentThread
AppWindow.TryCreateAsync AppWindow.Create
CoreWindow.Activate AppWindow.TryShowAsync AppWindow.Show

关闭

在 UWP 中,ApplicationView.TryConsolidateAsync 是用户发起关闭手势的编程等效项。 此合并概念(在 UWP 的 ApplicationView/CoreWindow 窗口化模型中)在 Win32 中不存在。 Win32 不要求窗口存在于单独线程中。 复制 UWP 的 ApplicationView/CoreWindow 窗口化模型需要开发人员创建新线程,并在其中创建新窗口。 在 Win32 模型下,默认系统行为是“关闭”>“隐藏”>“销毁”。

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
ApplicationView.TryConsolidateAsync AppWindow.CloseAsync AppWindow.Destroy

基本窗口自定义

从 UWP 迁移到 Windows 应用 SDK 时,可以从默认的 AppWindow 获得相同体验。 但如果需要,可以更改默认的 Microsoft.UI.Windowing.AppWindow,以获得自定义窗口化体验。 有关如何自定义窗口的详细信息,请参阅 Microsoft.UI.Windowing.AppWindow

调整窗口大小

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
ApplicationView.TryResizeView AppWindow.RequestSize AppWindow.Resize
CoreWindow.Bounds(在 C# 中通常显示为 CoreWindow.GetForCurrentThread.Bounds AppWindowPlacement.Size AppWindow.Size

定位窗口

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
不可用 AppWindow.GetPlacement AppWindow.Position
不可用 Appwindow.RequestMoveXxx AppWindow.Move

窗口标题

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
ApplicationView.Title AppWindow.Title AppWindow.Title

紧凑覆盖层和全屏

进入紧凑覆盖层或全屏的应用应该利用 Windows 应用 SDK AppWindowPresenter。 如果熟悉 UWP AppWindow,则你可能已熟悉演示器的概念。

没有从 UWP 应用窗口演示器到 Windows 应用 SDK 应用窗口演示器的 1:1 功能和行为映射。 如果你具有 UWP ApplicationView/CoreWindow 应用,则仍可在应用中实现紧凑覆盖层(画中画)或全屏窗口化体验,但演示器的概念对你来说可能是新概念。 有关应用窗口演示器的详细信息,请参阅演示器。 默认情况下,重叠的演示器在创建时会应用于 AppWindow。 除了默认值之外,CompactOverlay 和 FullScreen 是唯一可用的演示器。

紧凑覆盖层

如果使用 UWP 的 ApplicationViewMode 或 AppWindowPresentionKind 呈现紧凑覆盖层窗口,则应使用紧凑覆盖层 AppWindowPresenterKind。 Microsoft.UI.Windowing.CompactOverlayPresenter 仅支持三种 16:9 纵横比的固定窗口大小,用户无法调整大小。 应使用AppWindow.SetPresenter 更改 AppWindow 的呈现,而不是使用 ApplicationViewMode.TryEnterViewModeAsync 或 AppWindowPresenterKind.RequestPresentation。

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
ApplicationViewMode.CompactOverlay AppWindowPresentationKind.CompactOverlay AppWindowPresenterKind.CompactOverlay
ApplicationView.TryEnterViewModeAsync(带有 ApplicationViewMode.CompactOverlay AppWindowPresenter.RequestPresentation(带有 AppWindowPresenterKind.CompactOverlay AppWindow.SetPresenter(带有 AppWindowPresenterKind.CompactOverlay

全屏

如果使用 UWP 的 ApplicationViewWindowingMode 或 AppWindowPresentionKind 类呈现全屏窗口,则应使用全屏 AppWindowPresenterKind。 Windows 应用 SDK 仅支持限制最严格的全屏体验(即当 FullScreen 为 IsExclusive 时)。 对于 ApplicationView/CoreWindow,可以使用 ApplicationView.ExitFullScreenMode 使应用从全屏中退出。 使用演示器时,可以通过使用 AppWindow.SetPresenter 将演示器设置回重叠/默认值,使应用退出全屏。

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
ApplicationViewWindowingMode.FullScreen AppWindowPresentationKind.FullScreen AppWindowPresenterKind.FullScreen
ApplicationView.TryEnterFullScreenMode AppWindowPresenter.RequestPresentation(带有 AppWindowPresenterKind.FullScreen AppWindow.SetPresenter(带有 AppWindowPresenterKind.FullScreen

有关如何使用应用窗口演示器的更多详细信息,请参阅窗口化库示例。 它演示如何切换不同的应用窗口演示器状态。

自定义标题栏

注意

标题栏自定义 API 目前仅适用于 Windows 11。 建议在调用这些 API 之前,在代码中检查 AppWindowTitleBar.IsCustomizationSupported

如果应用使用默认标题栏,则迁移到 Win32 时无需额外的标题栏工作。 另一方面,如果 UWP 应用具有自定义标题栏,则可以在 Windows 应用 SDK 应用中重新创建以下方案。

  1. 自定义系统绘制的标题栏
  2. 应用绘制的自定义标题栏

使用 UWP ApplicationViewTitleBarCoreApplicationViewTitleBarAppWindowTitleBar 类的代码会迁移到使用 Windows 应用 SDK Microsoft.UI.Windowing.AppWindowTitleBar 类。

自定义系统绘制的标题栏

下面是颜色自定义 API 的表。

注意

AppWindowTitleBar.ExtendsContentIntoTitleBartrue 时,只有以下属性才支持透明度:AppWindowTitleBar.ButtonBackgroundColor、AppWindowTitleBar.ButtonInactiveBackgroundColor、AppWindowTitleBar.ButtonPressedBackgroundColor、AppWindowTitleBar.ButtonHoverBackgroundColor 和 AppWindowTitleBar.BackgroundColor(隐式设置)。

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
ApplicationViewTitleBar 的属性 AppWindowTitleBar 的属性 AppWindowTitleBar 的属性
BackgroundColor BackgroundColor BackgroundColor
ButtonBackgroundColor ButtonBackgroundColor ButtonBackgroundColor
ButtonForegroundColor ButtonForegroundColor ButtonForegroundColor
ButtonHoverBackgroundColor ButtonHoverBackgroundColor ButtonHoverBackgroundColor
ButtonHoverForegroundColor ButtonHoverForegroundColor ButtonHoverForegroundColor
ButtonInactiveBackgroundColor ButtonInactiveBackgroundColor ButtonInactiveBackgroundColor
ButtonInactiveForegroundColor ButtonInactiveForegroundColor ButtonInactiveForegroundColor
ButtonPressedBackgroundColor ButtonPressedBackgroundColor ButtonPressedBackgroundColor
ButtonPressedForegroundColor ButtonPressedForegroundColor ButtonPressedForegroundColor
ForegroundColor ForegroundColor ForegroundColor
InactiveBackgroundColor InactiveBackgroundColor InactiveBackgroundColor
InactiveForegroundColor InactiveForegroundColor InactiveForegroundColor

除了 AppWindow.Title API 外,这些 Windows 应用 SDK API 适用于进一步自定义系统绘制的标题栏。

应用绘制的自定义标题栏(完全自定义)

如果要迁移到使用 AppWindowTitleBar,建议在调用以下自定义标题栏 API 之前,在代码中检查 AppWindowTitleBar.IsCustomizationSupported

UWP ApplicationView/CoreWindow Windows 应用 SDK AppWindow
CoreApplicationViewTitleBar.ExtendViewIntoTitleBar AppWindowTitleBar.ExtendsContentIntoTitleBar
平台继续为你绘制最小化/最大化/关闭按钮,并上报遮挡信息。
CoreApplicationViewTitleBar.SystemOverlayLeftInset AppWindowTitleBar.LeftInset
CoreApplicationViewTitleBar.SystemOverlayRightInset AppWindowTitleBar.RightInset
CoreApplicationViewTitleBar.Height AppWindowTitleBar.Height
AppWindowTitleBarOcclusion
AppWindowTitleBar.GetTitleBarOcclusions
表示在 ExtendsContentIntoTitleBar 为 true 时将遮挡应用内容的应用窗口系统保留区域。 Windows 应用 SDK AppWindow 左右插入信息与标题栏高度一起提供相同的信息。
AppWindowTitleBar.LeftInsetAppWindowTitleBar.RightInsetAppWindowTitleBar.Height

这些 Windows 应用 SDK API 适用于完全标题栏自定义。

这些 UWP AppWindow API 没有直接 1:1 映射到 Windows 应用 SDK API。

有关如何使用 AppWindowTitleBar 的更多详细信息,请参阅窗口化库示例。 它演示如何创建自定义颜色标题栏以及如何绘制自定义标题栏。

事件处理

如果 UWP 应用使用 AppWindow.Changed 事件,可以将该代码迁移到 Microsoft.UI.Windowing.AppWindow.Changed 事件。

大小更改事件

迁移大小更改事件处理代码时,应切换到使用 Windows 应用 SDK AppWindowChangedEventArgs.DidSizeChange 属性。 如果应用窗口的大小发生更改,则值为 true;否则为 false

UWP ApplicationView/CoreWindow UWP AppWindow Windows 应用 SDK
CoreWindow.SizeChanged AppWindowChangedEventArgs.DidSizeChange AppWindowChangedEventArgs.DidSizeChange

MainPage 和 MainWindow

在 Visual Studio 中创建新 UWP 项目时,项目模板会提供 MainPage 类。 对于你的应用,你可能重命名了该类(和/或添加了更多页面和用户控件)。 项目模板还在 App 类的方法中提供导航代码。

在 Visual Studio 中创建新 Windows 应用 SDK 项目时,项目模板会提供 MainWindow 类(属于 Microsoft.UI.Xaml.Window),但是未提供 Page。 并且项目模板未提供任何导航代码。

但是,可以选择将页面和用户控件添加到 Windows 应用 SDK 项目。 例如,可以向项目添加新页面项(“WinUI”>“空白页(WinUI 3)”),并将它命名为 MainPage.xaml 或某个其他名称。 这会向项目添加类型为 Microsoft.UI.Xaml.Controls.Page 的新类。 随后,有关向项目添加导航代码的信息,请参阅是否需要实现页面导航?

对于足够简单的 Windows 应用 SDK 应用,无需创建页面或用户控件,可以将 XAML 标记和代码隐藏复制到 MainWindow 中。 但有关该工作流的例外情况的信息,请参阅 视觉状态管理器和 Page.Resources

将 CoreWindow.Dispatcher 更改为 Window.DispatcherQueue

UWP Windows.UI.Core.CoreWindow 类的一些用例迁移到 Windows 应用 SDK 的 Microsoft.UI.Xaml.Window

例如,如果在 UWP 应用中使用 Windows.UI.Core.CoreWindow.Dispatcher 属性,则解决方案不是迁移到 Microsoft.UI.Xaml.Window.Dispatcher 属性(始终返回 null)。 而是迁移到 Microsoft.UI.Xaml.Window.DispatcherQueue 属性,该属性返回 Microsoft.UI.Dispatching.DispatcherQueue

有关详细信息和代码示例,请参阅 将 Windows.UI.Core.CoreDispatcher 更改为 Microsoft.UI.Dispatching.DispatcherQueue