docs-maui/docs/fundamentals/windows.md

13 KiB

title description ms.date
.NET MAUI windows Learn how to use the .NET MAUI Window class to create, configure, show, and manage multi-window apps. 10/24/2023

.NET MAUI windows

The .NET Multi-platform App UI (.NET MAUI) xref:Microsoft.Maui.Controls.Window class provides the ability to create, configure, show, and manage multiple windows.

xref:Microsoft.Maui.Controls.Window defines the following properties:

These properties, with the exception of the Overlays property, are backed by xref:Microsoft.Maui.Controls.BindableProperty objects, which means that they can be targets of data bindings, and styled.

The xref:Microsoft.Maui.Controls.Window class defines the following events:

For more information about the lifecycle events, and their associated overrides, see App lifecycle.

The xref:Microsoft.Maui.Controls.Window class also defines the following modal navigation events:

The xref:Microsoft.Maui.Controls.VisualElement class has a Window property that exposes the parent xref:Microsoft.Maui.Controls.Window object. This property can be accessed from any page, layout, or view, to manipulate xref:Microsoft.Maui.Controls.Window objects.

Create a Window

By default, .NET MAUI creates a xref:Microsoft.Maui.Controls.Window object when you set the MainPage property to a xref:Microsoft.Maui.Controls.Page object in your App class. However, you can also override the CreateWindow method in your App class to create a xref:Microsoft.Maui.Controls.Window object:

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;
        }
    }
}

While the xref:Microsoft.Maui.Controls.Window class has a default constructor and a constructor that accepts a xref:Microsoft.Maui.Controls.Page argument, which represents the root page of the app, you can also call the base CreateWindow method to return the .NET MAUI created xref:Microsoft.Maui.Controls.Window object.

In addition, you can also create your own xref:Microsoft.Maui.Controls.Window-derived object:

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

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

        // Override Window methods
    }
}

The xref:Microsoft.Maui.Controls.Window-derived class can then be consumed by creating a MyWindow object in the CreateWindow override in your App class.

Regardless of how your xref:Microsoft.Maui.Controls.Window object is created, it will be the parent of the root page in your app.

Multi-window support

Multiple windows can be simultaneously opened on Android, iOS on iPad (iPadOS), Mac Catalyst, and Windows. This can be achieved by creating a xref:Microsoft.Maui.Controls.Window object and opening it using the OpenWindow method on the Application object:

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

The Application.Current.Windows collection, of type IReadOnlyList<Window> maintains references to all xref:Microsoft.Maui.Controls.Window objects that are registered with the Application object.

Windows can be closed with the Application.Current.CloseWindow method:

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

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

[!IMPORTANT] Multi-window support works on Android and Windows without additional configuration. However, additional configuration is required on iPadOS and Mac Catalyst.

iPadOS and macOS configuration

To use multi-window support on iPadOS and Mac Catalyst, add a class named SceneDelegate to the Platforms > iOS and Platforms > MacCatalyst folders:

using Foundation;
using Microsoft.Maui;
using UIKit;

namespace MyMauiApp;

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

Then, in the XML editor, open the Platforms > iOS > Info.plist file and the Platforms > MacCatalyst > Info.plist file and add the following XML to the end of each file:

<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>

[!IMPORTANT] Multi-window support doesn't work on iOS for iPhone.

Position and size a Window

The position and size of a window can be programmatically defined for a .NET MAUI app on Windows by setting the X, Y, Width, and Height properties on a xref:Microsoft.Maui.Controls.Window object.

[!WARNING] Mac Catalyst doesn't support resizing or repositioning windows programmatically by setting the X, Y, Width, and Height properties.

For example, to set the window position and size on launch you should override the CreateWindow method in your App class and set the X, Y, Width, and Height properties on a xref:Microsoft.Maui.Controls.Window object:

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
        };
}

Alternatively, a window can be positioned and sized by accessing the Window property from any page, layout, or view. For example, the following code shows how to position a window in the center of the screen:

// 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;

For information about obtaining the device's screen metrics, see Device display information.

Mac Catalyst

Mac Catalyst doesn't support resizing or repositioning windows programmatically. However, a workaround to enable resizing is to set the MinimumWidth and MaximumWidth properties to the desired width of the window, and the MinimumHeight and MaximumHeight properties to the desired height of the window. This will trigger a resize, and you can then revert the properties back to their original values:

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

::: moniker range=">=net-maui-8.0"

Decouple window management from the App class

Window management can be decoupled from the App class by creating a class that implements the xref:Microsoft.Maui.Controls.IWindowCreator interface, and adding your window management code in the xref:Microsoft.Maui.Controls.IWindowCreator.CreateWindow%2A method:

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;
    }
}

Then, in the MauiProgram class you should register your window management type as a dependency in the app's service container:

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

[!IMPORTANT] Ensure that your registration code specifies the IWindowCreator interface as well as its concrete type.

Then, ensure that your App class doesn't set the MainPage property:

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

Provided that the xref:Microsoft.Maui.Controls.IWindowCreator interface and its concrete type have been registered with the app's service container, and that the xref:Microsoft.Maui.Controls.Application.MainPage property of the xref:Microsoft.Maui.Controls.Application class isn't set, your registered type will be used to create the xref:Microsoft.Maui.Controls.Window.

::: moniker-end