Mostrare più visualizzazioni per un'app

Wireframe showing an app with multiple windows

Puoi aiutare gli utenti a essere più produttivi consentendo loro di visualizzare parti indipendenti della tua app in finestre separate. Quando crei più finestre per un'app, la barra delle applicazioni mostra ogni finestra separatamente. Gli utenti possono spostare, ridimensionare, mostrare e nascondere le finestre delle app in modo indipendente e passare da una finestra all'altra come se fossero app separate.

API importanti: Windows.UI.ViewManagement namespace, Windows.UI.WindowManagement namespace

Quando devono essere usate più visualizzazioni in un'app?

Numerosi scenari possono trarre vantaggio dall'uso di più visualizzazioni. Ecco alcuni esempi:

  • Un'app e-mail che consente agli utenti di visualizzare un elenco di messaggi ricevuti durante la composizione di un nuovo messaggio e-mail
  • Un'app rubrica che consente agli utenti di confrontare le info sul contatto per più contatti affiancati
  • Un'app lettore musicale che consente agli utenti di visualizzare il contenuto riprodotto esplorando, nel contempo, un elenco di altri brani musicali disponibili
  • Un'app appunti che consente agli utenti di copiare informazioni da una pagina di note a un'altra
  • Un'app di lettura che consente agli utenti di aprire diversi articoli per una lettura successiva, dopo aver potuto esplorare tutti i titoli in primo piano

Anche se il layout di ogni app è univoco, è consigliabile includere un pulsante per una "nuova finestra" in un percorso prevedibile, ad esempio l'angolo in alto a destra del contenuto che può essere aperto in una nuova finestra. Valuta anche se aggiungere un'opzione di menu di scelta rapida in "Apri in una nuova finestra".

Per creare istanze separate di un'app, anziché finestre separate per la stessa istanza, vedi Creare un'app di Windows a più istanze.

Host di windowing

Esistono diversi modi per ospitare contenuto di Windows in un'app.

  • CoreWindow/ApplicationView

    Una visualizzazione app è l'associazione 1:1 di un thread e una finestra usata dall'app per visualizzare il contenuto. La prima visualizzazione creata all'avvio dell'app è denominata visualizzazione principale. Ogni elemento CoreWindow/ApplicationView funziona nel proprio thread. La necessità di lavorare su thread dell'interfaccia utente diversi può complicare le app con più finestre.

    La visualizzazione principale di un'app è sempre ospitata in elemento ApplicationView. Il contenuto in una finestra secondaria può essere ospitato in un elemento ApplicationView o AppWindow.

    Per informazioni su come usare ApplicationView per mostrare finestre secondarie in un'app, vedi Usare ApplicationView.

  • AppWindow

    La classe AppWindow semplifica la creazione di app di Windows con più finestre perché funziona sullo stesso thread dell'interfaccia utente a partire dal quale viene creata.

    La classe AppWindow e altre API nello spazio dei nomi WindowManagement sono disponibili a partire da Windows 10, versione 1903 (SDK 18362). Se l'app è destinata a versioni di Windows 10 precedenti, devi usare ApplicationView per creare finestre secondarie.

    Per informazioni su come usare AppWindow per mostrare finestre secondarie in un'app, vedi Usare AppWindow.

    Nota

    AppWindow è attualmente disponibile in anteprima. Ciò significa che puoi inviare app che usano AppWindow allo Store, ma è noto che alcuni componenti della piattaforma e del framework non funzionano con AppWindow (vedi Limitazioni).

  • DesktopWindowXamlSource (isole XAML)

    Il contenuto XAML UWP di un'app Win32 (che usa HWND), noto anche come isole XAML, è ospitato in DesktopWindowXamlSource.

    Per altre informazioni sulle isole XAML, vedi Uso dell'API host XAML UWP in un'applicazione desktop.

Rendere il codice portabile tra gli host di windowing

Quando viene visualizzato contenuto XAML in un elemento CoreWindow, sono sempre presenti una classe ApplicationView e una classe Window XAML associate. Puoi usare le API di queste classi per ottenere informazioni quali ad esempio i limiti delle finestre. Per recuperare un'istanza di queste classi, usa il metodo statico CoreWindow.GetForCurrentThread, il metodo ApplicationView.GetForCurrentView o la proprietà Window.Current. Sono inoltre disponibili molte classi che usano il modello GetForCurrentView per recuperare un'istanza della classe, ad esempio DisplayInformation.GetForCurrentView.

Queste API funzionano perché esiste solo un singolo albero di contenuto XAML per ogni CoreWindow/ApplicationView e pertanto il codice XAML riconosce di essere ospitato nel contesto dell'elemento CoreWindow/ApplicationView specifico.

Quando il contenuto XAML viene eseguito in elemento AppWindow o DesktopWindowXamlSource, puoi disporre di più alberi di contenuto XAML in esecuzione contemporaneamente nello stesso thread. In questo caso, queste API non forniscono le informazioni corrette, perché il contenuto non è più in esecuzione nell'elemento CoreWindow/ApplicationView (e Window XAML) corrente.

Per verificare che il codice funzioni correttamente in tutti gli host di windowing, devi sostituire le API basate su CoreWindow, ApplicationView e Window con le nuove API che ottengono il contesto dalla classe XamlRoot. La classe XamlRoot rappresenta un albero di contenuto XAML e informazioni sul contesto in cui è ospitato, sia che si tratti di CoreWindow, AppWindow o DesktopWindowXamlSource. Questo livello di astrazione consente di scrivere lo stesso codice indipendentemente dall'host di windowing in cui viene eseguito il codice XAML.

Questa tabella mostra codice che non funziona correttamente negli host di windowing e il nuovo codice portabile con cui puoi sostituirlo, oltre ad alcune API che non è necessario modificare.

Se hai usato... Sostituisci con...
CoreWindow.GetForCurrentThread().Bounds uiElement.XamlRoot.Size
CoreWindow.GetForCurrentThread().SizeChanged uiElement.XamlRoot.Changed
CoreWindow.Visible uiElement.XamlRoot.IsHostVisible
CoreWindow.VisibilityChanged uiElement.XamlRoot.Changed
CoreWindow.GetForCurrentThread().GetKeyState Invariata. È supportata in AppWindow e DesktopWindowXamlSource.
CoreWindow.GetForCurrentThread().GetAsyncKeyState Invariata. È supportata in AppWindow e DesktopWindowXamlSource.
Window.Current Restituisce l'oggetto Window XAML principale che è strettamente associato all'elemento CoreWindow corrente. Vedi la nota dopo questa tabella.
Window.Current.Bounds uiElement.XamlRoot.Size
Window.Current.Content UIElement root = uiElement.XamlRoot.Content
Window.Current.Compositor Invariata. È supportata in AppWindow e DesktopWindowXamlSource.
VisualTreeHelper.FindElementsInHostCoordinates
Anche se il parametro UIElement è facoltativo, il metodo genera un'eccezione se non viene fornito un UIElement quando è ospitato in un'isola.
Specificare uiElement.XamlRoot come UIElement invece di lasciarlo vuoto.
VisualTreeHelper.GetOpenPopups
Nelle app di isole XAML genera un errore. Nelle app AppWindow restituisce popup aperti nella finestra principale.
VisualTreeHelper.GetOpenPopupsForXamlRoot(uiElement.XamlRoot)
FocusManager.GetFocusedElement FocusManager.GetFocusedElement(uiElement.XamlRoot)
contentDialog.ShowAsync() contentDialog.XamlRoot = uiElement.XamlRoot;
contentDialog.ShowAsync();
menuFlyout.ShowAt(null, new Point(10, 10)); menuFlyout.XamlRoot = uiElement.XamlRoot;
menuFlyout.ShowAt(null, new Point(10, 10));

Nota

Per il contenuto XAML in DesktopWindowXamlSource, esiste un elemento CoreWindow/Window sul thread, ma è sempre invisibile e ha una dimensione di 1x1. È ancora accessibile all'app, ma non restituisce limiti significativi o visibilità.

Per il contenuto XAML in un elemento AppWindow, esisterà sempre esattamente un elemento CoreWindow sullo stesso thread. Se chiami un'API GetForCurrentView o GetForCurrentThread, tale API restituirà un oggetto che riflette lo stato di CoreWindow sul thread, non uno degli elementi AppWindows che potrebbero essere in esecuzione su tale thread.

Cosa fare e cosa non fare

  • Fornisci un punto di ingresso chiaro per la visualizzazione secondaria usando il glifo "Apri nuova finestra".
  • Comunica lo scopo della visualizzazione secondaria agli utenti.
  • Garantisci che l'app funziona correttamente in un'unica visualizzazione e che gli utenti apriranno una visualizzazione secondaria solo per comodità.
  • Non basarti sulla visualizzazione secondaria per fornire notifiche o altri elementi visivi temporanei.