Window 类概述
在 .NET MAUI 中,Window 类负责创建、配置、显示和管理多个窗口,是多平台应用程序 UI 的核心组件之一。通过 Window 类,开发者可以控制窗口的布局方向、尺寸、位置以及生命周期事件,从而构建灵活的用户界面。
Window 属性详解
Window 类定义了一系列属性,用于控制窗口的行为和外观。除 Overlays 属性外,其余属性均由 BindableProperty 支持,这意味着它们可以作为数据绑定的目标,并支持样式设置。
- FlowDirection: 定义窗口 UI 元素的布局方向,例如从左到右或从右到左。
- Height 和 Width: 在 Windows 平台上,分别指定窗口的高度和宽度,类型为
double。 - MaximumHeight 和 MaximumWidth: 表示桌面平台上窗口的最大高度和宽度,有效值介于 0 和
double.PositiveInfinity之间。 - MinimumHeight 和 MinimumWidth: 表示桌面平台上窗口的最小高度和宽度,有效值同样介于 0 和
double.PositiveInfinity之间。 - Overlays: 类型为
IReadOnlyCollection<IWindowOverlay>,代表窗口叠加层的集合。 - Page: 类型为
Page,表示窗口中显示的页面。此属性是Window类的内容属性,因此通常无需显式设置。 - Title: 字符串类型,表示窗口的标题。
- X 和 Y: 在 Windows 平台上,分别指定窗口的 X 和 Y 坐标,用于定位窗口位置。
Window 事件详解
Window 类定义了多个事件,用于响应窗口的生命周期状态变化和用户交互。
- Created: 窗口创建时触发。
- Resumed: 窗口从睡眠状态恢复时触发。
- Activated 和 Deactivated: 分别对应窗口激活和停用状态。
- Stopped: 窗口停止时触发。
- Destroying: 窗口被销毁时触发。
- SizeChanged: 在桌面平台上,当窗口大小变更时触发。
- Backgrounding: 在 iOS 和 Mac Catalyst 上,当窗口关闭或进入后台状态时触发,附带
BackgroundingEventArgs对象,可用于保存状态信息。 - DisplayDensityChanged: 在 Android 和 Windows 上,当窗口的每英寸有效点数(DPI)变更时触发,附带
DisplayDensityChangedEventArgs对象。
此外,Window 类还定义了模态导航相关事件,如 ModalPopped、ModalPopping、ModalPushed、ModalPushing 和 PopCanceled,用于管理模态视图的推送和弹出操作。通过这些事件,开发者可以精细控制窗口的行为和用户体验。
创建窗口
默认情况下,当在 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中,将LaunchMode从SingleTop改为Multiple。 - iPadOS 和 Mac Catalyst: 需要添加
SceneDelegate类,并在Info.plist文件中配置多场景支持。 - 注意: 多窗口不支持 iPhone 版本的 iOS。
窗口位置与大小调整
在 Windows 平台上,可以通过设置 Window 对象的 X、Y、Width 和 Height 属性,以编程方式定义窗口的位置和尺寸。例如,在 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 上,不支持直接通过属性设置调整窗口大小或位置,但可以通过临时设置 MinimumWidth、MaximumWidth、MinimumHeight 和 MaximumHeight 属性来触发调整,然后再恢复原始值。
分离窗口管理与 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 桌面平台,其他平台会忽略此代码路径。