Partager via


Afficher plusieurs fenêtres pour votre application

Dans votre application WinUI 3, vous pouvez afficher le contenu de votre application dans les fenêtres secondaires tout en travaillant sur le même thread d’interface utilisateur sur chaque fenêtre.

L’application WinUI 3 Gallery inclut des exemples interactifs de la plupart des contrôles, des caractéristiques et des fonctionnalités de WinUI 3. Obtenir l’application à partir du Microsoft Store ou obtenir le code source sur GitHub

Conseil / Astuce

Une raison courante d’utiliser plusieurs fenêtres consiste à permettre aux onglets TabView d’être déplacés dans une nouvelle fenêtre. Pour plus d’informations et d’exemples spécifiques à ce scénario, consultez le détachement d'onglet dans l'article la vue des onglets.

Présentation de l’API

Voici quelques-unes des API importantes que vous utilisez pour afficher du contenu dans plusieurs fenêtres.

XAML Window et AppWindow

Les classes Window et AppWindow peuvent être utilisées pour afficher une partie d'une application dans une fenêtre secondaire. Une fonctionnalité importante des fenêtres WinUI est que chaque instance partage le même thread de traitement de l’interface utilisateur (y compris le répartiteur d’événements) à partir duquel ils ont été créés, ce qui simplifie les applications multi-fenêtres.

Consultez la vue d’ensemble des fenêtres pour le kit de développement logiciel (SDK) WinUI et Windows App pour obtenir une explication plus détaillée de Window et AppWindow.

AppWindowPresenter

L’API AppWindowPresenter vous permet de basculer facilement les fenêtres en configurations prédéfinies comme FullScreen ou CompactOverlay. Pour plus d’informations, consultez Gérer les fenêtres d’application.

XamlRoot

La classe XamlRoot contient une arborescence d’éléments XAML, la connecte à l’objet hôte de fenêtre et fournit des informations telles que la taille et la visibilité. Vous ne créez pas d’objet XamlRoot directement. Au lieu de cela, un élément XAML est créé lorsque vous attachez un élément XAML à un Window. Vous pouvez ensuite utiliser la propriété UIElement.XamlRoot pour récupérer xamlRoot.

WindowId

WindowId est un identificateur unique pour une fenêtre d’application. Il est créé automatiquement et identifie à la fois le AppWindow et le HWND Win32 de niveau supérieur auquel il est associé.

À partir d’un élément visuel, vous pouvez accéder à UIElement.XamlRoot ; puis XamlRoot.ContentIslandEnvironment ; la propriété ContentIslandEnvironment.AppWindowId contient ensuite l’ID de fenêtre dans laquelle l’uiElement se trouve.

Afficher une nouvelle fenêtre

Vous pouvez créer un nouveau Window en XAML ou dans le code. Si vous créez un Window code XAML, vous créez en fait une sous-classe de la Window classe. Par exemple, consultez MainWindow.xaml qui est créé par le modèle d'application de Visual Studio.

Examinons les étapes à suivre pour afficher le contenu dans une nouvelle fenêtre.

Pour créer une fenêtre avec XAML

  1. Dans le volet Explorateur de solutions , cliquez avec le bouton droit sur le nom du projet, puis sélectionnez Ajouter > un nouvel élément...
  2. Dans la boîte de dialogue Ajouter un nouvel élément , sélectionnez WinUI dans la liste des modèles sur le côté gauche de la fenêtre.
  3. Sélectionnez le modèle vide Window .
  4. Nommez le fichier.
  5. Appuyez sur Ajouter.

Pour afficher une nouvelle fenêtre

  1. Instanciez une nouvelle instance de Window, ou une Window sous-classe si vous avez créé une Window sous-classe avec un .xaml fichier.

    Window newWindow = new Window();
    
  2. Créez le contenu de la fenêtre.

    Si vous avez créé une Window sous-classe avec un .xaml fichier, vous pouvez ajouter le contenu de la fenêtre directement en XAML. Sinon, vous ajoutez le contenu dans le code, comme indiqué ici.

    Il est courant de créer un code XAML Frame, puis de naviguer Frame vers un code XAML [Page](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.page où vous avez défini le contenu de votre application. Pour plus d’informations sur les frames et les pages, consultez Navigation pair à pair entre deux pages.

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

    Toutefois, vous pouvez afficher n’importe quel contenu XAML dans le AppWindow, pas seulement un Frame et Page. Par exemple, vous pouvez afficher un seul contrôle, comme ColorPicker, comme illustré plus tard.

  3. Définissez votre contenu XAML sur la propriété Content de l’objet Window.

    newWindow.Content = contentFrame;
    
  4. Appelez le Window. Activez la méthode pour afficher la nouvelle fenêtre.

    newWindow.Activate();
    

Suivre les instances de Window

Vous souhaiterez peut-être avoir accès aux Window instances provenant d’autres parties de votre application, mais après avoir créé une instance d’un Window, il n’existe aucun moyen de l’accéder à partir d’un autre code, sauf si vous conservez une référence à celle-ci. Par exemple, vous souhaiterez peut-être gérer l'événement Window SizeChanged dans MainPage pour réorganiser les éléments de l'interface utilisateur lorsque la fenêtre est redimensionnée, ou vous pourriez avoir un bouton "tout fermer" qui ferme toutes les instances suivies de Window.

Dans ce cas, vous devez utiliser l’identificateur WindowId unique pour suivre les instances de fenêtre dans un Dictionary, avec la valeur WindowId comme Key et l’instance Window en tant que Value. (Les API de déchirure de tabulation TabView sont également utilisées WindowId pour suivre Windows.)

Dans votre App classe, créez l’objet Dictionary en tant que propriété statique. Ensuite, ajoutez chaque page au Dictionary moment où vous le créez et supprimez-la lorsque la page est fermée.

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

Le code suivant crée une nouvelle fenêtre lorsqu’un bouton est cliqué dans MainPage. TrackWindow ajoute la nouvelle fenêtre au ActiveWindowsDictionary, et gère l'événement Window.Closed pour le supprimer de ActiveWindows lorsque la fenêtre est fermée.

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

Obtenez une fenêtre avec suivi depuis le code de votre application

Pour accéder à une instance Window depuis votre code d'application, vous devez obtenir le WindowId pour la fenêtre actuelle afin de la récupérer à partir de l'élément statique Dictionary dans votre classe App. Vous devez le faire dans le gestionnaire d’événements Loaded de la page plutôt que dans le constructeur afin que XamlRoot ne soit pas 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];
        }
    }
}