Compartir a través de


Mostrar varias ventanas para la aplicación

En la aplicación WinUI 3, puedes mostrar el contenido de la aplicación en ventanas secundarias mientras sigue trabajando en el mismo subproceso de interfaz de usuario en cada ventana.

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 3. Obtén la aplicación desde la Microsoft Store o consigue el código fuente en GitHub

Sugerencia

Una razón común para usar varias ventanas es permitir que las pestañas de TabView se separen en una nueva ventana. Para obtener información y ejemplos específicos de este escenario, consulte Tirar de la pestaña en el artículo Vista de pestañas.

Introducción a la API

Estas son algunas de las API importantes que usa para mostrar contenido en varias ventanas.

XAML Window y AppWindow

Las Window clases y AppWindow se pueden usar para mostrar una parte de una aplicación en una ventana secundaria. Una característica importante de las ventanas winUI es que cada instancia comparte el mismo subproceso de procesamiento de la interfaz de usuario (incluido el distribuidor de eventos) desde el que se crearon, lo que simplifica las aplicaciones de varias ventanas.

Consulte Información general sobre ventanas para WinUI y Windows App SDK para obtener una explicación más detallada de Window y AppWindow.

AppWindowPresenter

La API de AppWindowPresenter permite cambiar fácilmente las ventanas a configuraciones predefinidas como FullScreen o CompactOverlay. Para obtener más información, consulta Administrar ventanas de aplicaciones.

XamlRoot

La clase XamlRoot contiene un árbol de elementos XAML, lo conecta al objeto host de ventana y proporciona información como el tamaño y la visibilidad. No creas un objeto XamlRoot directamente. En su lugar, se crea uno cuando se adjunta un elemento XAML a un Window. A continuación, puedes usar la propiedad UIElement.XamlRoot para recuperar xamlRoot.

WindowId

WindowId es un identificador único para una ventana de aplicación. Se crea automáticamente e identifica tanto el AppWindow como el HWND de nivel superior de Win32 con el que está asociado.

Desde un elemento visual, puedes acceder a UIElement.XamlRoot; a continuación , XamlRoot.ContentIslandEnvironment; a continuación, la propiedad ContentIslandEnvironment.AppWindowId contiene el identificador de la ventana en la que está el UIElement.

Mostrar una nueva ventana

Puedes crear un nuevo Window en XAML o en código. Si creas un Window en XAML, realmente vas a crear una subclase de la Window clase . Por ejemplo, vea MainWindow.xaml, que está creado por la plantilla de la aplicación de Visual Studio.

Echemos un vistazo a los pasos para mostrar el contenido en una nueva ventana.

Para crear una nueva ventana con XAML

  1. En el panel Explorador de soluciones, haga clic con el botón derecho en el nombre del proyecto y seleccione Agregar > nuevo elemento...
  2. En el cuadro de diálogo Agregar nuevo elemento , seleccione WinUI en la lista de plantillas del lado izquierdo de la ventana.
  3. Seleccione la plantilla En blanco Window.
  4. Dele un nombre al archivo.
  5. Presione Agregar.

Para mostrar una nueva ventana

  1. Cree una nueva instancia de Window, o de una subclase de Window si creó una subclase de Window con un archivo .xaml.

    Window newWindow = new Window();
    
  2. Cree el contenido de la ventana.

    Si creaste una Window subclase con un .xaml archivo, puedes agregar el contenido de la ventana directamente en XAML. De lo contrario, agregue el contenido en el código como se muestra aquí.

    Es habitual crear un XAML Frame, y a continuación, navegar por el Frame a un XAML [Page](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.page) donde has definido el contenido de la aplicación. Para obtener más información sobre marcos y páginas, consulta Navegación de punto a punto entre dos páginas.

    Frame contentFrame = new Frame();
    contentFrame.Navigate(typeof(SecondaryPage));
    

    Sin embargo, puedes mostrar cualquier contenido XAML en AppWindow, no solo un Frame y Page. Por ejemplo, puede mostrar solo un solo control, como ColorPicker, como se muestra más adelante.

  3. Establezca su contenido XAML en la propiedad Content de Window.

    newWindow.Content = contentFrame;
    
  4. Llame al método Window.Activate para mostrar la nueva ventana.

    newWindow.Activate();
    

Seguimiento de instancias de Window

Es posible que desee tener acceso a las instancias de Window en otras partes de su aplicación, pero después de crear una instancia de Window, no hay forma de acceder a ella desde otros fragmentos de código a menos que mantenga una referencia a ella. Por ejemplo, puede que quiera manejar el evento Window.SizeChanged en MainPage para reorganizar los elementos de la interfaz de usuario cuando se cambie el tamaño de la ventana, o podría tener un botón de "cerrar todo" que cierre todas las instancias rastreadas de Window.

En este caso, debe usar el identificador WindowId único para realizar el seguimiento de las instancias de ventana en un Dictionary, con el WindowId como el Key y la instancia de Window como el Value. Las API de cierre de pestañas TabView también utilizan WindowId para monitorizar Windows.

En su clase App, cree la Dictionary como una propiedad estática. A continuación, agregue cada página al Dictionary momento de crearla y quítela cuando se cierre la página.

// App.xaml.cs
public partial class App : Application
{
    private Window? _window;
    public static Dictionary<WindowId, Window> ActiveWindows { get; set; } = new Dictionary<WindowId, Window>();

    // ...

    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        _window = new MainWindow();
        _window.Activate();
        // Track the new window in the dictionary.
        ActiveWindows.Add(_window.AppWindow.Id, _window);
    }
}

El código siguiente crea una nueva ventana cuando se hace clic en un botón en MainPage. El método TrackWindow agrega la nueva ventana a ActiveWindowsDictionary, y maneja el evento Window.Closed para quitarla de ActiveWindows cuando se cierra la ventana.

// MainPage.xaml.cs
private Window CreateWindow()
{
    Window newWindow = new Window();

    // Configure the window.
    newWindow.AppWindow.Resize(new SizeInt32(1200, 800));
    newWindow.Title = "Window " + newWindow.AppWindow.Id.Value.ToString();
    newWindow.SystemBackdrop = new MicaBackdrop();

    TrackWindow(newWindow);
    return newWindow;
}

private void TrackWindow(Window window)
{
    window.Closed += (sender, args) => {
        App.ActiveWindows.Remove(window.AppWindow.Id, out window);
    };
    App.ActiveWindows.Add(window.AppWindow.Id, window);
}

Obtención de una ventana con seguimiento desde el código de la aplicación

Para acceder a una instancia de Window desde el código de la aplicación, debe obtener el WindowId para que la ventana actual la recupere de la Dictionary estática de la clase App. Debe hacerlo en el controlador de eventos Loaded de la página en lugar de en el constructor para que XamlRoot no sea null.

public sealed partial class SecondaryPage : Page
{
    Window window;

    public SecondaryPage()
    {
        InitializeComponent();
        Loaded += AppWindowPage_Loaded;
    }

    private void AppWindowPage_Loaded(object sender, RoutedEventArgs e)
    {
        // Get the reference to this Window that was stored when it was created.
        // Do this in the Page Loaded handler rather than the constructor to
        // ensure that the XamlRoot is created and attached to the Window.
        WindowId windowId = this.XamlRoot.ContentIslandEnvironment.AppWindowId;

        if (App.ActiveWindows.ContainsKey(windowId))
        {
            window = App.ActiveWindows[windowId];
        }
    }
}