.NET MAUI 窗口

.NET Multi-platform App UI (.NET MAUI) Window 类提供创建、配置、显示和管理多窗口的功能。

Window 定义以下属性:

  • FlowDirection,类型为 FlowDirection,定义窗口的 UI 元素布局的方向。
  • Height,类型为 double,指定 Windows 上窗口的高度。
  • MaximumHeight,类型为 double,表示桌面平台上窗口的最大高度。 有效值介于 0 和 double.PositiveInfinity 之间。
  • MaximumWidth,类型为 double,表示桌面平台上窗口的最大宽度。 有效值介于 0 和 double.PositiveInfinity 之间。
  • MinimumHeight,类型为 double,表示桌面平台上窗口的最小高度。 有效值介于 0 和 double.PositiveInfinity 之间。
  • MinimumWidth,类型为 double,表示桌面平台上窗口的最小宽度。 有效值介于 0 和 double.PositiveInfinity 之间。
  • Overlays,类型为 IReadOnlyCollection<IWindowOverlay>,表示窗口覆盖的集合。
  • Page,类型为 Page,指示窗口显示的页面。 此属性是 Window 类的内容属性,因此不需要显式设置。
  • Title,类型为 string,表示窗口的标题。
  • Width,类型为 double,指定 Windows 上的窗口宽度。
  • X,类型为 double,指定 Windows 上窗口的 X 坐标。
  • Y,类型为 double,指定 Windows 上窗口的 Y 坐标。

所有这些属性(Overlays 属性除外)都由 BindableProperty 对象提供支持,这意味着它们可以作为数据绑定的目标,并进行样式设置。

Window 类定义以下事件:

  • Created,在创建窗口时引发。
  • Resumed,当窗口从休眠状态恢复时引发。
  • Activated,在激活窗口时引发。
  • Deactivated,在停用窗口时引发。
  • Stopped,在窗口停止时引发。
  • Destroying,在窗口被销毁时引发。
  • SizeChanged,当窗口更改大小时在桌面平台上引发。
  • Backgrounding 附带 BackgroundingEventArgs 对象,当窗口关闭或进入后台状态时,iOS 和 Mac Catalyst 上会引发该对象。 此事件可用于将任何 string 状态保存到 BackgroundingEventArgs 对象的 State 属性,OS 将保留该状态,直到恢复窗口时为止。 恢复窗口后,状态将通过 CreateWindow 方法的 IActivationState 参数提供。
  • <xref:Microsoft.Maui.Controls.WindowDisplayDensityChanged,以及附带的 DisplayDensityChangedEventArgs 对象,当 Android 和 Windows 上窗口的每英寸有效点数 (DPI) 更改时,将引发该对象。

要详细了解生命周期事件及其关联替代,请参阅应用生命周期

Window 类还定义以下模式导航事件:

  • ModalPopped,包含 ModalPoppedEventArgs,以模式方式弹出视图时引发。
  • ModalPopping,包含 ModalPoppingEventArgs,以模式方式弹出视图时引发。
  • ModalPushed,包含 ModalPushedEventArgs,以模式方式推送视图后引发。
  • ModalPushing,包含 ModalPushingEventArgs,以模式方式推送视图时引发。
  • PopCanceled,在取消模式弹出时引发。

VisualElement 类具有公开父级 Window 对象的 Window 属性。 可以从任何页面、布局或视图访问此属性,以操作 Window 对象。

创建窗口

默认情况下,在 App 类中将 MainPage 属性设置为 Page 对象时,.NET MAUI 会创建一个 Window 对象。 但是,也可以重写 App 类中的 CreateWindow 方法以创建 Window 对象:

namespace MyMauiApp
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new MainPage();
        }

        protected override Window CreateWindow(IActivationState activationState)
        {
            Window window = base.CreateWindow(activationState);

            // Manipulate Window object

            return window;
        }
    }
}

虽然 Window 类有默认构造函数和接受 Page 参数(表示应用的根页)的构造函数,但还可以调用基 CreateWindow 方法来返回 Window 对象创建的 .NET MAUI。

此外,还可以创建自己的 Window 派生对象:

namespace MyMauiApp
{
    public class MyWindow : Window
    {
        public MyWindow() : base()
        {
        }

        public MyWindow(Page page) : base(page)
        {
        }

        // Override Window methods
    }
}

然后,可以通过在 App 类的 CreateWindow 重写中创建 MyWindow 对象来使用 Window 派生类。

无论 Window 对象是如何创建的,它都将是应用中根页的父级。

多窗口支持

可以在 Android、iPad 上的 iOS (iPadOS)、Mac Catalyst 和 Windows 上同时打开多个窗口。 可以通过创建 Window 对象,并使用 Application 对象上的 OpenWindow 方法将其打开的方式实现此目的:

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

IReadOnlyList<Window> 类型的 Application.Current.Windows 集合保持对使用 Application 对象注册的所有 Window 对象的引用。

可以使用 Application.Current.CloseWindow 方法关闭 Windows:

// Close a specific window
Application.Current.CloseWindow(secondWindow);

// Close the active window
Application.Current.CloseWindow(GetParentWindow());

重要

多窗口支持适用于 Android 和 Windows,无需进行其他配置。 但是,iPadOS 和 Mac Catalyst 需要额外的配置。

iPadOS 和 macOS 配置

若要在 iPadOS 和 Mac Catalyst 上使用多窗口支持,请将一个名为 SceneDelegate 的类添加至“平台”>“iOS”以及“平台”>“MacCatalyst”文件夹:

using Foundation;
using Microsoft.Maui;
using UIKit;

namespace MyMauiApp;

[Register("SceneDelegate")]
public class SceneDelegate : MauiUISceneDelegate
{
}

然后,在 XML 编辑器中,打开“平台”>“iOS”> Info.plist 文件以及“平台”>“MacCatalyst”> Info.plist 文件,并将以下 XML 添加到每个文件的末尾:

<key>UIApplicationSceneManifest</key>
<dict>
  <key>UIApplicationSupportsMultipleScenes</key>
  <true/>
  <key>UISceneConfigurations</key>
  <dict>
    <key>UIWindowSceneSessionRoleApplication</key>
    <array>
      <dict>
        <key>UISceneConfigurationName</key>
        <string>__MAUI_DEFAULT_SCENE_CONFIGURATION__</string>
        <key>UISceneDelegateClassName</key>
        <string>SceneDelegate</string>
      </dict>
    </array>
  </dict>
</dict>

重要

多窗口支持不适用于 iOS for iPhone。

调整窗口的位置和大小

可以通过设置 Window 对象的 XYWidthHeight 属性,以编程方式为 Windows 上的 .NET MAUI 应用定义窗口的位置和大小。

警告

Mac Catalyst 不支持通过设置 XYWidthHeight 属性以编程方式调整窗口的大小或位置。

例如,若要在启动时设置窗口位置和大小,应重写 App 类中的 CreateWindow 方法,并设置 Window 对象的 XYWidthHeight 属性:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }

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

或者,可以通过从任何页面、布局或视图访问 Window 属性来调整窗口的位置和大小。 例如,以下代码显示如何将窗口置于屏幕中心:

// Get display size
var displayInfo = DeviceDisplay.Current.MainDisplayInfo;

// Center the window
Window.X = (displayInfo.Width / displayInfo.Density - Window.Width) / 2;
Window.Y = (displayInfo.Height / displayInfo.Density - Window.Height) / 2;

有关获取设备屏幕指标的信息,请参阅设备显示信息

Mac Catalyst

Mac Catalyst 不支持以编程方式调整窗口的大小或位置。 但是,启用大小调整的解决方法是将 MinimumWidthMaximumWidth 属性设置为所需的窗口宽度,并将 MinimumHeightMaximumHeight 属性设置为所需的窗口高度。 这会触发重设大小,然后可以将属性还原,返回到其原始值:

Window.MinimumWidth = 700;
Window.MaximumWidth = 700;
Window.MinimumHeight = 500;
Window.MaximumHeight = 500;

// Give the Window time to resize
Dispatcher.Dispatch(() =>
{
    Window.MinimumWidth = 0;
    Window.MinimumHeight = 0;
    Window.MaximumWidth = double.PositiveInfinity;
    Window.MaximumHeight = double.PositiveInfinity;
});

从 App 类分离窗口管理

通过创建实现 IWindowCreator 接口的类并在 CreateWindow 方法中添加窗口管理代码,可以将窗口管理与 App 类分离:

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>();

重要

确保注册代码指定 IWindowCreator 接口及其具体类型。

然后,确保 App 类未设置 MainPage 属性:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }
}

如果 IWindowCreator 接口及其具体类型已注册到应用的服务容器中,并且未设置 Application 类的 MainPage 属性,则注册的类型将用于创建 Window