Compartir a través de


Ventanas de .NET MAUI

La clase Window de la interfaz de usuario de aplicaciones multiplataforma de .NET (.NET MAUI) proporciona la capacidad de crear, configurar, mostrar y administrar varias ventanas.

Window define las siguientes propiedades:

  • FlowDirection, de tipo FlowDirection, define la dirección en la que se diseña el elemento de interfaz de usuario de la ventana.
  • Height, de tipo double, especifica el alto de la ventana en Windows.
  • MaximumHeight, de tipo double, representa el alto máximo de la ventana en plataformas de escritorio. Los valores válidos están comprendidos entre 0 y double.PositiveInfinity.
  • MaximumWidth, de tipo double, representa el ancho máximo de la ventana en plataformas de escritorio. Los valores válidos están comprendidos entre 0 y double.PositiveInfinity.
  • MinimumHeight, de tipo double, representa el alto mínimo de la ventana en plataformas de escritorio. Los valores válidos están comprendidos entre 0 y double.PositiveInfinity.
  • MinimumWidth, de tipo double, representa el ancho mínimo de la ventana en plataformas de escritorio. Los valores válidos están comprendidos entre 0 y double.PositiveInfinity.
  • Overlays, de tipo IReadOnlyCollection<IWindowOverlay>, representa la colección de superposiciones de ventana.
  • Page, de tipo Page, indica la página que muestra la ventana. Esta es la propiedad de contenido de la clase Window y, por lo tanto, no hay que establecerla explícitamente.
  • Title, de tipo string, representa el título de la ventana.
  • Width, de tipo double, especifica el ancho de la ventana en Windows.
  • X, de tipo double, especifica la coordenada X de la ventana en Windows.
  • Y, de tipo double, especifica la coordenada Y de la ventana en Windows.

Todas estas propiedades, excepto la propiedad Overlays, están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos y con estilo.

La clase Window define los eventos siguientes:

  • Created, que se genera cuando se crea la ventana.
  • Resumed, que se genera cuando la ventana se reanuda desde un estado de suspensión.
  • Activated, que se genera cuando se activa la ventana.
  • Deactivated, que se genera cuando se desactiva la ventana.
  • Stopped, que se genera cuando se detiene la ventana.
  • Destroying, que se genera cuando se destruye la ventana.
  • SizeChanged, que se genera en plataformas de escritorio cuando cambia el tamaño de la ventana.
  • Backgrounding, con un objeto complementario BackgroundingEventArgs, que se genera en iOS y Mac Catalyst cuando la ventana está cerrada o entra en un estado de segundo plano. Este evento se puede usar para conservar cualquier estado string en la propiedad State del objeto BackgroundingEventArgs, que el SO conservará hasta que sea el momento de reanudar la ventana. Cuando se reanuda la ventana, el estado se proporciona a través del argumento IActivationState al método CreateWindow.
  • DisplayDensityChanged, con un objeto complementario DisplayDensityChangedEventArgs, que se genera en Android y Windows cuando los puntos efectivos por pulgada (PPP) de la ventana han cambiado.

Para obtener más información sobre los eventos de ciclo de vida y sus invalidaciones asociadas, consulta Ciclo de vida de la aplicación.

La clase Window también define los siguientes eventos de navegación modal:

  • ModalPopped, con ModalPoppedEventArgs, que se genera cuando se ha abierto una vista de forma modal.
  • ModalPopping, con ModalPoppingEventArgs, que se genera cuando se abre una vista de forma modal.
  • ModalPushed, con ModalPushedEventArgs, que se genera después de que una vista se haya insertado de forma modal.
  • ModalPushing, con ModalPushingEventArgs, que se genera cuando se inserta una vista de forma modal.
  • PopCanceled, que se genera cuando se cancela un elemento emergente modal.

La VisualElement clase tiene una propiedad Window que expone el objeto primario Window. Se puede acceder a esta propiedad desde cualquier página, diseño o vista, para manipular objetos Window.

Creación de una ventana

De forma predeterminada, .NET MAUI crea un objeto Window cuando se establece la propiedad MainPage en un objeto Page de la clase App. Sin embargo, también puedes invalidar el método CreateWindow de la clase App para crear un objeto 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;
        }
    }
}

Aunque la clase Window tiene un constructor predeterminado y un constructor que acepta un argumento Page, que representa la página raíz de la aplicación, también puedes llamar al método base CreateWindow para devolver el objeto Window creado por .NET MAUI.

Además, también puedes crear tu propio objeto Window derivado:

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

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

        // Override Window methods
    }
}

La clase Window derivada se puede consumir mediante la creación de un objeto MyWindow en la invalidación CreateWindow de tu clase App

Independientemente de cómo se cree el objeto Window, será el elemento primario de la página raíz de la aplicación.

Compatibilidad con varias ventanas

Se pueden abrir varias ventanas simultáneamente en Android, iOS en iPad (iPadOS), Mac Catalyst y Windows. Esto se puede lograr mediante la creación de un objeto Window y su apertura mediante el método OpenWindow en el objeto Application:

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

La colección Application.Current.Windows, de tipo IReadOnlyList<Window>, mantiene referencias a todos los objetos Window registrados con el objeto Application.

Una ventana específica se puede traer al frente en Mac Catalyst y Windows con el método Application.Current.ActivateWindow:

Application.Current?.ActivateWindow(secondWindow);

Windows se puede cerrar con el método Application.Current.CloseWindow:

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

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

Importante

La compatibilidad con varias ventanas funciona en Windows sin especificar ninguna configuración adicional. Sin embargo, se requiere una configuración adicional en Android, iPadOS y Mac Catalyst.

Configuración de Android

Para usar la compatibilidad con varias ventanas en Android, debes cambiar el modo de inicio MainActivity en Plataformas > Android > MainActivity.cs de LaunchMode.SingleTop a LaunchMode.Multiple:

using Android.App;
using Android.Content.PM;
using Android.OS;

namespace MyMauiApp;

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.Multiple, ...)]
public class MainActivity : MauiAppCompatActivity
{
}

Configuración de iPadOS y macOS

Para usar la compatibilidad con varias ventanas en iPadOS y Mac Catalyst, agrega una clase denominada SceneDelegate a las carpetas Plataformas > iOS y Plataformas > MacCatalyst:

using Foundation;
using Microsoft.Maui;
using UIKit;

namespace MyMauiApp;

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

Después, en el editor XML, abre el archivo Platforms > iOS > Info.plist y el archivo Platforms > MacCatalyst > Info.plist, y agrega el siguiente XML al final de cada archivo:

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

Importante

La compatibilidad con varias ventanas no funciona en iOS para iPhone.

Posicionar y dimensionar una ventana

La posición y el tamaño de una ventana se pueden definir mediante programación para una aplicación .NET MAUI en Windows al establecer las propiedades X, Y, Width y Height en un objeto Window.

Advertencia

Mac Catalyst no admite el cambio de tamaño ni el cambio de posición de las ventanas mediante programación estableciendo las propiedades X, Y, Width y Height.

Por ejemplo, para establecer la posición y el tamaño de la ventana al iniciar, debes invalidar el método CreateWindow en la clase App y establecer las propiedades X, Y, Width y Height en un objeto Window:

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

Como alternativa, se puede colocar y ajustar el tamaño de una ventana accediendo a la propiedad Window desde cualquier página, diseño o vista. Por ejemplo, el código siguiente muestra cómo colocar una ventana en el centro de la pantalla:

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

Para obtener información sobre cómo obtener las métricas de pantalla del dispositivo, consulta Información de pantalla del dispositivo.

Mac Catalyst

Mac Catalyst no admite el cambio de tamaño ni el cambio de posición de las ventanas mediante programación. Sin embargo, una solución alternativa para habilitar el cambio de tamaño es establecer las propiedades MinimumWidth y MaximumWidth en el ancho deseado de la ventana, y las propiedades MinimumHeight y MaximumHeight en el alto deseado de la ventana. Esto desencadenará un cambio de tamaño y después podrás revertir las propiedades a sus valores originales:

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

Desacoplar la administración de ventanas de la clase App

La administración de ventanas se puede desacoplar de la clase App mediante la creación de una clase que implemente la interfaz IWindowCreator y agregue el código de administración de ventanas en el método 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;
    }
}

Después en la clase MauiProgram debes registrar el tipo de administración de ventanas como una dependencia en el contenedor de servicios de la aplicación:

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

Importante

Asegúrate de que el código de registro especifica la interfaz IWindowCreator, así como su tipo concreto.

Después asegúrate de que la clase App no establece la propiedad MainPage:

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

Si la interfaz IWindowCreator y su tipo concreto se han registrado con el contenedor de servicios de la aplicación y la propiedad MainPage de la clase Application no esté establecida, el tipo registrado se usará para crear Window.