Scenari avanzati per le isole XAML nelle app desktopo Win32 C++

Importante

Questo argomento usa o menziona tipi del repository GitHub CommunityToolkit/Microsoft.Toolkit.Win32. Per informazioni importanti sul supporto per le isole XAML, vedere l'avviso sulle isole XAML nel repository citato.

Gli articoli Ospitare un controllo UWP standard e Ospitare un controllo UWP personalizzato contengono istruzioni ed esempi per l'hosting di isole XAML in un'app desktop Win32 C++. Tuttavia, gli esempi di codice presenti in questi articoli non consentono di gestire molti scenari avanzati che le applicazioni desktop possono avere necessità di gestire per offrire un'esperienza utente uniforme. Questo articolo fornisce indicazioni per alcuni di questi scenari e fa riferimento a esempi di codice correlati.

Input tastiera

Per gestire correttamente l'input da tastiera per ogni isola XAML, l'applicazione deve passare tutti i messaggi di Windows al framework XAML UWP in modo che alcuni messaggi possano essere elaborati correttamente. A tale scopo, in un punto dell'applicazione in grado di accedere al ciclo di messaggi, esegui il cast dell'oggetto DesktopWindowXamlSource per ogni isola XAML a un'interfaccia COM IDesktopWindowXamlSourceNative2. Chiama quindi il metodo PreTranslateMessage di questa interfaccia e passa il messaggio corrente.

Spostamento dello stato attivo della tastiera

Quando l'utente si sposta tra gli elementi dell'interfaccia utente nell'applicazione usando la tastiera, ad esempio premendo TAB o un tasto freccia/di direzione, dovrai spostare lo stato attivo a livello di codice all'interno e all'esterno dell'oggetto DesktopWindowXamlSource. Quando la navigazione da tastiera dell'utente raggiunge DesktopWindowXamlSource, sposta lo stato attivo sul primo oggetto Windows.UI.Xaml.UIElement nell'ordine di navigazione per l'interfaccia utente, continua a spostare lo stato attivo sugli oggetti Windows.UI.Xaml.UIElement seguenti quando l'utente scorre gli elementi e quindi risposta lo stato attivo da DesktopWindowXamlSource sull'elemento padre dell'interfaccia utente.

L'API host XAML della piattaforma UWP offre diversi tipi e membri che consentono di eseguire queste attività.

  • Quando la navigazione da tastiera entra in DesktopWindowXamlSource, viene generato l'evento GotFocus. Gestisci questo evento e sposta lo stato attivo a livello di codice sul primo Windows.UI.Xaml.UIElement ospitato usando il metodo NavigateFocus.

  • Quando l'utente si trova in corrispondenza dell'ultimo elemento attivabile di DesktopWindowXamlSource e preme il tasto TAB o un tasto di direzione, viene generato l'evento TakeFocusRequested. Gestisci questo evento e sposta lo stato attivo a livello di codice sull'elemento attivabile successivo nell'applicazione host. Ad esempio, in un'applicazione WPF in cui DesktopWindowXamlSource è ospitato in System.Windows.Interop.HwndHost, puoi usare il metodo MoveFocus per trasferire lo stato attivo all'elemento attivabile successivo nell'applicazione host.

Per esempi che illustrano come eseguire questa operazione nel contesto di un'applicazione di esempio funzionante, vedi i file di codice seguenti:

Gestire le modifiche al layout

Quando l'utente modifica le dimensioni dell'elemento padre dell'interfaccia utente, dovrai gestire eventuali modifiche necessarie al layout per assicurarti che i controlli UWP vengano visualizzati come previsto. Di seguito sono riportati alcuni scenari importanti da prendere in considerazione.

  • In un'applicazione desktop di Windows Win32 C++, quando l'applicazione gestisce il messaggio WM_SIZE, può riposizionare l'isola XAML ospitata usando la funzione SetWindowPos. Per un esempio, vedi il file di codice SampleApp.cpp.

  • Quando l'elemento padre dell'interfaccia utente deve ottenere le dimensioni dell'area rettangolare necessaria per adattarsi a Windows.UI.Xaml.UIElement ospitato in DesktopWindowXamlSource, chiama il metodo Measure di Windows.UI.Xaml.UIElement. Ad esempio:

  • Quando le dimensioni dell'elemento padre dell'interfaccia utente cambiano, chiama il metodo Arrange di Windows.UI.Xaml.UIElement radice ospitato in DesktopWindowXamlSource. Ad esempio:

    • In un'applicazione WPF puoi eseguire questa operazione dal metodo ArrangeOverride dell'oggetto HwndHost che ospita DesktopWindowXamlSource. Per un esempio, vedi il file WindowsXamlHost.Layout.cs nel toolkit della Community Windows.

    • In un'applicazione Windows Forms puoi eseguire questa operazione dal gestore per l'evento SizeChanged dell'oggetto Control che ospita DesktopWindowXamlSource. Per un esempio, vedi il file WindowsXamlHost.Layout.cs nel toolkit della Community Windows.

Gestire le modifiche DPI

Il framework XAML della piattaforma UWP gestisce automaticamente le modifiche DPI per i controlli UWP ospitati (ad esempio, quando l'utente trascina la finestra tra monitor con DPI dello schermo diversi). Per un'esperienza ottimale, è consigliabile che l'applicazione Windows Forms, WPF o applicazione desktop C++ sia configurata in modo da essere sensibile ai valori DPI del monitor.

Per configurare l'applicazione in modo da essere sensibile ai valori DPI del monitor, aggiungi al tuo progetto un manifesto dell'assembly side-by-side e imposta l'elemento <dpiAwareness> su PerMonitorV2. Per altre informazioni su questo valore, vedi la descrizione di DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
        </windowsSettings>
    </application>
</assembly>