Uso dell'API di hosting XAML UWP

Importante

Questo argomento usa o menziona i tipi del repository CommunityToolkit/Microsoft.Toolkit.Win32 GitHub. Per informazioni importanti sul supporto delle isole XAML UWP, vedi l'avviso XAML Islands Notice in tale repository.

Le app desktop non UWP (incluse le app desktop C++ (Win32), macchine virtuali Windows e Windows Forms) possono usare l'API di hosting XAML UWP per ospitare i controlli XAML UWP in qualsiasi elemento dell'interfaccia utente associato a un handle di finestra (HWND). Per una panoramica di questa funzionalità, vedi Ospitare controlli XAML UWP nelle app desktop (isole XAML UWP).For an overview of this feature, see Host UWP XAML controls in desktop apps (UWP XAML Islands).

L'API di hosting XAML UWP è la scelta giusta per l'app desktop?

L'API di hosting XAML UWP fornisce l'infrastruttura di basso livello per l'hosting di controlli XAML UWP nelle app desktop. Alcuni tipi di app desktop hanno la possibilità di usare API alternative e più convenienti per raggiungere questo obiettivo.

  • Se hai un'app desktop C++ e vuoi ospitare i controlli XAML UWP nella tua app, devi usare l'API di hosting XAML UWP. Non esistono alternative per questi tipi di app.

  • Per le app macchine virtuali Windows e Windows Forms, raccomandiamo fortemente di usare i controlli XAML Island .NET nel Windows Community Toolkit anziché usare direttamente l'API di hosting XAML UWP. Questi controlli usano l'API di hosting XAML UWP internamente e implementano tutto il comportamento che altrimenti devi gestire se hai usato direttamente l'API di hosting XAML UWP, incluse le modifiche di spostamento e layout della tastiera.

Poiché è consigliabile che solo le app desktop C++ usino l'API di hosting XAML UWP, questo articolo fornisce principalmente istruzioni ed esempi per le app desktop C++. Tuttavia, puoi usare l'API di hosting XAML UWP in macchine virtuali Windows e Windows Forms app, se scegli. Questo articolo fa riferimento al codice sorgente pertinente per i controlli host per macchine virtuali Windows e Windows Forms in Windows Community Toolkit per vedere come viene usata l'API di hosting XAML UWP da tali controlli.

Informazioni su come usare l'API di hosting XAML

Per seguire istruzioni dettagliate con esempi di codice per l'uso dell'API di hosting XAML nelle app desktop C++, vedi questi articoli:

Samples

Il modo in cui usi l'API di hosting XAML UWP nel codice dipende dal tipo di app, dalla progettazione della tua app e da altri fattori. Per illustrare come usare questa API nel contesto di un'app completa, questo articolo fa riferimento al codice degli esempi seguenti.

Desktop C++ (Win32)

Gli esempi seguenti illustrano come usare l'API di hosting XAML UWP in un'app desktop C++:

  • Esempio di semplice isola XAML. Questo esempio illustra una implementazione di base per ospitare un controllo XAML UWP in un'app desktop C++ non impacchettata.

  • XAML Island con esempio di controllo personalizzato. Questo esempio illustra un'implementazione completa per ospitare un controllo XAML UWP personalizzato in un'app desktop C++ confezionata, nonché la gestione di altri comportamenti, ad esempio l'input della tastiera e la navigazione dello stato attivo.

macchine virtuali Windows e Windows Forms

Il controllo WindowsXamlHost in Windows Community Toolkit funge da esempio di riferimento per l'uso dell'API di hosting XAML UWP nelle app macchine virtuali Windows e Windows Forms. Il codice sorgente è disponibile nelle posizioni seguenti:

Annotazioni

Ti consigliamo vivamente di utilizzare i controlli .NET di XAML Island nel Windows Community Toolkit anziché utilizzare direttamente l'API di hosting XAML UWP nelle app macchine virtuali Windows e Windows Forms. I collegamenti di esempio macchine virtuali Windows e Windows Forms in questo articolo sono solo a scopo illustrativo.

Architettura dell'API

L'API di hosting XAML UWP include questi principali tipi di Windows Runtime e interfacce COM.

Tipo o interfaccia Descrzione
WindowsXamlManager Questa classe rappresenta il framework XAML UWP. Questa classe fornisce un singolo metodo static InitializeForCurrentThread che inizializza il framework XAML UWP nel thread corrente nell'app desktop.
DesktopWindowXamlSource Questa classe rappresenta un'istanza del contenuto XAML UWP che stai ospitando nella tua app desktop. Il membro più importante di questa classe è la proprietà Content . Puoi assegnare questa proprietà a un oggetto Windows.UI.Xaml.UIElement che vuoi ospitare. Questa classe include anche altri membri per indirizzare la navigazione dello stato attivo della tastiera all'interno e all'esterno delle isole XAML.
IDesktopWindowXamlSourceNative Questa interfaccia COM fornisce il metodo AttachToWindow , che usi per associare un'isola XAML nella tua app a un elemento dell'interfaccia utente padre. Ogni oggetto DesktopWindowXamlSource implementa questa interfaccia.
IDesktopWindowXamlSourceNative2 Questa interfaccia COM fornisce il metodo PreTranslateMessage , che consente al framework XAML UWP di elaborare correttamente determinati messaggi di Windows. Ogni oggetto DesktopWindowXamlSource implementa questa interfaccia.

Il diagramma seguente illustra la gerarchia di oggetti in un'isola XAML ospitata in un'app desktop.

  • A livello di base è l'elemento dell'interfaccia utente nella tua app in cui vuoi ospitare l'isola XAML. Questo elemento dell'interfaccia utente deve avere un handle di finestra (HWND). Esempi di elementi dell'interfaccia utente in cui è possibile ospitare un'isola XAML includono un window per le app desktop C++, System.Windows.Interop.HwndHost per le app macchine virtuali Windows e un System.Windows.Forms.Control per le app Windows Forms.

  • Al livello successivo è un oggetto DesktopWindowXamlSource . Questo oggetto fornisce l'infrastruttura per ospitare l'isola XAML. Il codice è responsabile della creazione di questo oggetto e del collegamento all'elemento dell'interfaccia utente padre.

  • Quando crei un oggetto DesktopWindowXamlSource, questo oggetto crea automaticamente una finestra figlio nativa per ospitare il controllo XAML UWP. Questa finestra figlia nativa è per lo più astratta dal tuo codice, ma è possibile accedere al relativo handle (HWND) se necessario.

  • Infine, al livello superiore è il controllo XAML UWP che vuoi ospitare nella tua app desktop. Può trattarsi di qualsiasi oggetto UWP che deriva da Windows. UI. Xaml.UIElement, incluso qualsiasi controllo XAML UWP fornito da Windows SDK e controlli utente personalizzati.

Architettura DesktopWindowXamlSource

Annotazioni

Quando si ospitano isole XAML UWP in un'app desktop, è possibile avere più alberi di contenuto XAML in esecuzione nello stesso thread contemporaneamente. Per accedere all'elemento radice di un albero di contenuti XAML in una XAML Island e ottenere informazioni relative al contesto in cui è ospitata, usare la classe XamlRoot. Le API CoreWindow, ApplicationView e Window non forniscono le informazioni corrette per le isole XAML UWP. Per altre informazioni, vedere questa sezione.

Procedure consigliate

Quando si usa l'API di hosting XAML UWP, seguire queste procedure consigliate per ogni thread che ospita controlli XAML UWP:

Risoluzione dei problemi

Errore durante l'uso dell'API di hosting XAML UWP in un'app UWP

Problema Risoluzione
L'app riceve un'eccezione COMException con il messaggio seguente: "Impossibile attivare DesktopWindowXamlSource. Questo tipo non può essere usato in un'app UWP." o "Non è possibile attivare WindowsXamlManager. Questo tipo non può essere usato in un'app UWP." Questo errore indica che si sta tentando di usare l'API di hosting XAML UWP (in particolare, si sta tentando di creare un'istanza dei tipi DesktopWindowXamlSource o WindowsXamlManager ) in un'app UWP. L'API di hosting XAML UWP deve essere usata solo nelle app desktop non UWP, ad esempio macchine virtuali Windows, Windows Forms e applicazioni desktop C++.

Errore durante il tentativo di usare i tipi WindowsXamlManager o DesktopWindowXamlSource

Problema Risoluzione
L'app riceve un'eccezione con il messaggio seguente: "WindowsXamlManager e DesktopWindowXamlSource sono supportati per le app destinate a Windows versione 10.0.18226.0 e successive. Controllare il manifesto dell'applicazione o il manifesto del pacchetto e verificare che la proprietà MaxTestedVersion sia aggiornata". Questo errore indica che l'applicazione ha tentato di usare il WindowsXamlManager o DesktopWindowXamlSource tipi nell'API di hosting XAML UWP, ma il sistema operativo non è in grado di determinare se l'app è stata compilata per Windows 10, versione 1903 o successiva. L'API di hosting XAML UWP è stata introdotta per la prima volta come anteprima in una versione precedente di Windows 10, ma è supportata solo a partire da Windows 10 versione 1903.

Per risolvere questo problema, creare un pacchetto MSIX per l'app ed eseguirlo oppure installare il pacchetto NuGet Microsoft.Toolkit.Win32.UI.SDK nel tuo progetto.

Errore durante il collegamento a una finestra in un thread diverso

Problema Risoluzione
L'app riceve una COMException con il messaggio seguente: "Il metodo AttachToWindow non è riuscito perché l'HWND specificato è stato creato su un diverso thread." Questo errore indica che l'applicazione ha chiamato il metodo IDesktopWindowXamlSourceNative::AttachToWindow e l'ha passato il valore HWND di una finestra creata in un thread diverso. È necessario passare a questo metodo l'HWND di una finestra creata nello stesso thread del codice da cui si sta chiamando il metodo.

Errore durante il collegamento a una finestra in una finestra di primo livello diversa

Problema Risoluzione
L'app riceve una COMException con il seguente messaggio: "Il metodo AttachToWindow non è riuscito perché l'HWND specificato discende da una finestra principale diversa rispetto all'HWND precedentemente passato ad AttachToWindow nello stesso thread". Questo errore indica che l'applicazione ha chiamato il metodo IDesktopWindowXamlSourceNative::AttachToWindow e gli ha passato l'HWND di una finestra che discende da una finestra di livello superiore diversa rispetto a quella specificata in una chiamata precedente a questo metodo sullo stesso thread.

Dopo che l'applicazione chiama AttachToWindow in un determinato thread, tutti gli altri oggetti DesktopWindowXamlSource sullo stesso thread possono collegarsi solo a finestre discendenti della stessa finestra di primo livello passata alla prima chiamata a AttachToWindow. Quando tutti gli oggetti DesktopWindowXamlSource vengono chiusi per un determinato thread, il successivo DesktopWindowXamlSource è quindi libero di collegarsi a qualsiasi finestra.

Per risolvere questo problema, chiudere tutti gli oggetti DesktopWindowXamlSource associati ad altre finestre di primo livello in questo thread o creare un nuovo thread per desktopWindowXamlSource.