.NET MAUI Window类全面解析:属性、事件与多窗口管理

Viewed 0

Window 类概述

在 .NET MAUI 中,Window 类负责创建、配置、显示和管理多个窗口,是多平台应用程序 UI 的核心组件之一。通过 Window 类,开发者可以控制窗口的布局方向、尺寸、位置以及生命周期事件,从而构建灵活的用户界面。

Window 属性详解

Window 类定义了一系列属性,用于控制窗口的行为和外观。除 Overlays 属性外,其余属性均由 BindableProperty 支持,这意味着它们可以作为数据绑定的目标,并支持样式设置。

  • FlowDirection: 定义窗口 UI 元素的布局方向,例如从左到右或从右到左。
  • HeightWidth: 在 Windows 平台上,分别指定窗口的高度和宽度,类型为 double
  • MaximumHeightMaximumWidth: 表示桌面平台上窗口的最大高度和宽度,有效值介于 0 和 double.PositiveInfinity 之间。
  • MinimumHeightMinimumWidth: 表示桌面平台上窗口的最小高度和宽度,有效值同样介于 0 和 double.PositiveInfinity 之间。
  • Overlays: 类型为 IReadOnlyCollection<IWindowOverlay>,代表窗口叠加层的集合。
  • Page: 类型为 Page,表示窗口中显示的页面。此属性是 Window 类的内容属性,因此通常无需显式设置。
  • Title: 字符串类型,表示窗口的标题。
  • XY: 在 Windows 平台上,分别指定窗口的 X 和 Y 坐标,用于定位窗口位置。

Window 事件详解

Window 类定义了多个事件,用于响应窗口的生命周期状态变化和用户交互。

  • Created: 窗口创建时触发。
  • Resumed: 窗口从睡眠状态恢复时触发。
  • ActivatedDeactivated: 分别对应窗口激活和停用状态。
  • Stopped: 窗口停止时触发。
  • Destroying: 窗口被销毁时触发。
  • SizeChanged: 在桌面平台上,当窗口大小变更时触发。
  • Backgrounding: 在 iOS 和 Mac Catalyst 上,当窗口关闭或进入后台状态时触发,附带 BackgroundingEventArgs 对象,可用于保存状态信息。
  • DisplayDensityChanged: 在 Android 和 Windows 上,当窗口的每英寸有效点数(DPI)变更时触发,附带 DisplayDensityChangedEventArgs 对象。

此外,Window 类还定义了模态导航相关事件,如 ModalPoppedModalPoppingModalPushedModalPushingPopCanceled,用于管理模态视图的推送和弹出操作。通过这些事件,开发者可以精细控制窗口的行为和用户体验。

创建窗口

默认情况下,当在 App 类中设置 MainPage 属性时,.NET MAUI 会自动创建 Window 对象。但开发者也可以重写 App 类中的 CreateWindow 方法来自定义窗口创建过程。

例如,以下代码展示了如何重写 CreateWindow 方法来操作窗口对象:

namespace MyMauiApp
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new MainPage();
        }

        protected override Window CreateWindow(IActivationState activationState)
        {
            Window window = base.CreateWindow(activationState);
            // 在此处操作窗口对象
            return window;
        }
    }
}

Window 类提供默认构造函数和接受 Page 参数的构造函数,后者代表应用程序的根页面。开发者还可以创建自定义的 Window 派生类,并在 CreateWindow 方法中实例化,以实现更复杂的窗口逻辑。

多窗口支持

在 Android、iPadOS、Mac Catalyst 和 Windows 平台上,.NET MAUI 支持同时打开多个窗口。通过创建新的 Window 对象并调用 Application.Current.OpenWindow 方法,可以启动额外窗口。

例如:

Window secondWindow = new Window(new MyPage());
Application.Current?.OpenWindow(secondWindow);

已注册的窗口可通过 Application.Current.Windows 集合进行管理,该集合类型为 IReadOnlyList<Window>。在 Mac Catalyst 和 Windows 上,可以使用 Application.Current.ActivateWindow 方法将特定窗口置于前台,或使用 Application.Current.CloseWindow 方法关闭窗口。

平台特定配置

多窗口支持在不同平台上可能需要额外配置:

  • Android: 在 MainActivity.cs 中,将 LaunchModeSingleTop 改为 Multiple
  • iPadOS 和 Mac Catalyst: 需要添加 SceneDelegate 类,并在 Info.plist 文件中配置多场景支持。
  • 注意: 多窗口不支持 iPhone 版本的 iOS。

窗口位置与大小调整

在 Windows 平台上,可以通过设置 Window 对象的 XYWidthHeight 属性,以编程方式定义窗口的位置和尺寸。例如,在 CreateWindow 方法中初始化窗口时设置这些属性:

protected override Window CreateWindow(IActivationState activationState) =>
    new Window(new AppShell())
    {
        Width = 700,
        Height = 500,
        X = 100,
        Y = 100
    };

此外,可以从任何页面、布局或视图访问 Window 属性来动态调整窗口。例如,将窗口居中显示:

var displayInfo = DeviceDisplay.Current.MainDisplayInfo;
Window.X = (displayInfo.Width / displayInfo.Density - Window.Width) / 2;
Window.Y = (displayInfo.Height / displayInfo.Density - Window.Height) / 2;

在 Mac Catalyst 上,不支持直接通过属性设置调整窗口大小或位置,但可以通过临时设置 MinimumWidthMaximumWidthMinimumHeightMaximumHeight 属性来触发调整,然后再恢复原始值。

分离窗口管理与 App 类

为了将窗口管理逻辑与 App 类分离,可以实现 IWindowCreator 接口,并在 CreateWindow 方法中添加窗口管理代码。首先,创建实现该接口的类:

public class WindowCreator : IWindowCreator
{
    public Window CreateWindow(Application app, IActivationState activationState)
    {
        var window = new Window(new ContentPage
        {
            Content = new Grid
            {
                new Label
                {
                    Text = "Hello from IWindowCreator",
                    HorizontalOptions = LayoutOptions.Center,
                    VerticalOptions = LayoutOptions.Center
                }
            }
        });
        return window;
    }
}

然后,在 MauiProgram 类中将该类型注册为依赖服务:

builder.Services.AddSingleton<IWindowCreator, WindowCreator>();

确保 App 类未设置 MainPage 属性,系统将自动使用注册的 IWindowCreator 实现来创建窗口。

Windows 平台特定功能

在 Windows 上,可以启用或禁用窗口的最小化和最大化按钮。通过获取底层的 WinUI 窗口并调整其呈现器属性,可以实现此功能。例如,以下代码禁用最小化和最大化按钮:

#if WINDOWS
using Microsoft.Maui.Platform;
using Microsoft.UI.Windowing;

public static void ConfigureWindowButtons(Window window)
{
    var nativeWindow = (MauiWinUIWindow)window.Handler.PlatformView;
    var appWindow = nativeWindow.AppWindow;

    if (appWindow.Presenter is OverlappedPresenter presenter)
    {
        presenter.IsMinimizable = false;
        presenter.IsMaximizable = false;
    }
}
#endif

此代码应在应用程序启动期间或显示次要窗口时调用。注意,这些属性仅适用于 Windows 桌面平台,其他平台会忽略此代码路径。

0 Answers