Condividi tramite


Mostra più finestre per l'app

Nell'app WinUI 3 puoi visualizzare il contenuto dell'app nelle finestre secondarie mentre lavori sullo stesso thread dell'interfaccia utente in ogni finestra.

Icona della raccolta WinUI 3 L'app Raccolta WinUI 3 include esempi interattivi di controlli e funzionalità WinUI. Ottenere l'app dal Microsoft Store o esplorare il codice sorgente in GitHub.

Suggerimento

Un motivo comune per usare più finestre è consentire il trascinamento delle schede TabView in una nuova finestra. Per informazioni ed esempi specifici di questo scenario, vedere Tab tear-out nell'articolo Visualizzazione tab.

Panoramica delle API

Ecco alcune delle API importanti usate per visualizzare il contenuto in più finestre.

XAML Window e AppWindow

Le Window classi e AppWindow possono essere usate per visualizzare una parte di un'app in una finestra secondaria. Una funzionalità importante delle finestre WinUI è che ogni istanza condivide lo stesso thread di elaborazione dell'interfaccia utente (incluso il dispatcher eventi) da cui sono stati creati, semplificando le app a più finestre.

Vedere Panoramica di Windows per WinUI e Windows App SDK per una spiegazione più dettagliata di Window e AppWindow.

AppWindowPresenter

L'API AppWindowPresenter consente di cambiare facilmente le finestre in configurazioni predefinite come FullScreen o CompactOverlay. Per altre informazioni, vedere Gestire le finestre delle app.

XamlRoot

La classe XamlRoot contiene un albero degli elementi XAML, lo connette all'oggetto host della finestra e fornisce informazioni come dimensioni e visibilità. Non crei direttamente un oggetto XamlRoot. Al contrario, ne viene creato uno quando si collega un elemento XAML a un oggetto Window. Puoi quindi usare la proprietà UIElement.XamlRoot per recuperare XamlRoot.

WindowId

WindowId è un identificatore univoco per una finestra dell'app. Viene creato automaticamente e identifica sia il AppWindow che il Win32 HWND di primo livello a cui è associato.

Da un elemento visivo, puoi accedere a UIElement.XamlRoot; quindi XamlRoot.ContentIslandEnvironment; quindi la proprietà ContentIslandEnvironment.AppWindowId contiene l'ID della finestra in cui si trova l'UIElement.

Mostra una nuova finestra

Puoi creare un nuovo Window in XAML o nel codice. Se crei un oggetto Window in XAML, stai effettivamente creando una sottoclasse della Window classe . Ad esempio, vedere MainWindow.xaml creato dal modello di app Visual Studio.

Esaminiamo i passaggi per visualizzare il contenuto in una nuova finestra.

Per creare una nuova finestra con XAML

  1. Nel riquadro Solution Explorer fare clic con il pulsante destro del mouse sul nome del progetto e scegliere Aggiungi > Nuovo elemento...
  2. Nella finestra di dialogo Aggiungi nuovo elemento selezionare WinUI nell'elenco dei modelli sul lato sinistro della finestra.
  3. Selezionare il modello Vuoto Window .
  4. Assegnare un nome al file.
  5. Premere Aggiungi.

Per visualizzare una nuova finestra

  1. Instanziare un nuovo Window, oppure una sottoclasse di Window se hai creato una sottoclasse di Window con un file .xaml.

    Window newWindow = new Window();
    
  2. Creare il contenuto della finestra.

    Se hai creato una Window sottoclasse con un .xaml file, puoi aggiungere il contenuto della finestra direttamente in XAML. In caso contrario, aggiungere il contenuto nel codice, come illustrato di seguito.

    È comune creare un codice XAML Frame, quindi passare Frame a un codice XAML [Page](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.page in cui è stato definito il contenuto dell'app. Per ulteriori informazioni su frame e pagine, consulta la navigazione peer-to-peer tra due pagine .

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

    Tuttavia, è possibile visualizzare qualsiasi contenuto XAML in AppWindow, non solo un Frame e Page. Ad esempio, è possibile visualizzare solo un singolo controllo, ad esempio ColorPicker, come illustrato più avanti.

  3. Impostare il contenuto XAML sulla proprietà Content dell'oggetto Window.

    newWindow.Content = contentFrame;
    
  4. Chiamare il metodo Window.Attivare per visualizzare la nuova finestra.

    newWindow.Activate();
    

Tenere traccia delle istanze di Window

Potresti voler avere accesso alle istanze di Window da altre parti della tua app, ma dopo aver creato un'istanza di un Window, non è possibile accedervi da altro codice dell'applicazione, a meno che non si mantenga un riferimento. Ad esempio, è possibile gestire l'evento Window.SizeChanged in MainPage per riorganizzare gli elementi dell'interfaccia utente quando la finestra viene ridimensionata, oppure è possibile avere un pulsante "Chiudi tutto" che chiude tutte le istanze monitorate di Window.

In questo caso, è necessario usare l'identificatore univoco WindowId per monitorare le istanze della finestra in un oggetto Dictionary, con WindowId come Key e l'istanza Window come Value. (TabView API di tab tear-out utilizzano anche WindowId per monitorare Windows.)

Nella tua classe, crea App come proprietà statica. Aggiungere quindi ogni pagina a Dictionary quando viene creata e rimuoverla quando la pagina viene chiusa.

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

Il codice seguente crea una nuova finestra quando si fa clic su un pulsante in MainPage. Il TrackWindow metodo aggiunge la nuova finestra a ActiveWindowsDictionarye gestisce .Window Evento chiuso da cui rimuoverlo quando ActiveWindows la finestra viene chiusa.

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

Ottenere una finestra rilevata dal codice dell'app

Per accedere a un'istanza di Window dal codice dell'app, è necessario ottenere WindowId per la finestra corrente, al fine di recuperarla dal Dictionary statico nella classe App. È consigliabile eseguire questa operazione nel gestore eventi Loaded della pagina anziché nel costruttore in modo che XamlRoot non nullsia .

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