Usando a API de hospedagem XAML UWP

Importante

Este tópico usa ou menciona tipos do repositório CommunityToolkit/Microsoft.Toolkit.Win32 GitHub. Para obter informações importantes sobre o suporte às Ilhas XAML UWP, consulte o Aviso sobre XAML Islands nesse repositório.

Aplicativos desktop não UWP (incluindo aplicativos de desktop C++ (Win32), WPF e Windows Forms) podem usar a UWP XAML hosting API para hospedar controles UWP XAML em qualquer elemento da interface do usuário associado a um identificador de janela (HWND). Para obter uma visão geral desse recurso, consulte Hospedar controles XAML UWP em apps desktop (UWP XAML Islands).

A API de hospedagem XAML UWP é a escolha certa para seu aplicativo da área de trabalho?

A API de hospedagem XAML UWP fornece a infraestrutura de baixo nível para hospedar controles XAML UWP em aplicativos da área de trabalho. Alguns tipos de aplicativos da área de trabalho têm a opção de usar APIs alternativas e mais convenientes para atingir essa meta.

  • Se você tiver um aplicativo de área de trabalho C++ e quiser hospedar controles XAML UWP em seu aplicativo, deverá usar a API de hospedagem XAML UWP. Não há alternativas para esses tipos de aplicativos.

  • Para os aplicativos de WPF e Windows Forms, é altamente recomendável que você use os controles .NET XAML Island no Community Toolkit do Windows, em vez de usar diretamente a API de hospedagem de XAML UWP. Esses controles usam a API de hospedagem XAML da UWP internamente e implementam todo o comportamento que você precisaria tratar se usasse a API de hospedagem XAML UWP diretamente, incluindo navegação por teclado e alterações de layout.

Como recomendamos que apenas os aplicativos de área de trabalho do C++ usem a API de hospedagem de XAML UWP, este artigo fornece principalmente instruções e exemplos para aplicativos da área de trabalho do C++. No entanto, você pode usar a API de hospedagem XAML UWP em aplicativos WPF e Windows Forms, se desejar. Este artigo aponta para o código-fonte relevante para os controles host para WPF e Windows Forms no kit de ferramentas da comunidade Windows para que você possa ver como a API de hospedagem XAML UWP é usada por esses controles.

Saiba como usar a API de Hospedagem XAML

Para seguir as instruções passo a passo com exemplos de código para usar a API de Hospedagem XAML em aplicativos da área de trabalho do C++, consulte estes artigos:

Samples

A maneira como você usa a API de hospedagem XAML UWP em seu código depende do tipo de aplicativo, do design do aplicativo e de outros fatores. Para ajudar a ilustrar como usar essa API no contexto de um aplicativo completo, este artigo refere-se ao código dos exemplos a seguir.

C++ de área de trabalho (Win32)

Os exemplos a seguir demonstram como usar a API de hospedagem de XAML UWP em um aplicativo de área de trabalho C++:

  • Exemplo simples de XAML Island. Este exemplo demonstra uma implementação básica de hospedagem de um controle XAML UWP em um aplicativo de área de trabalho C++ não empacotado.

  • XAML Island com exemplo de controle personalizado. Este exemplo demonstra uma implementação completa da hospedagem de um controle XAML UWP personalizado em um aplicativo de área de trabalho C++ empacotado, bem como o tratamento de outros comportamentos, como entrada de teclado e navegação de foco.

WPF e Windows Forms

O controle WindowsXamlHost no Windows Community Toolkit serve como um exemplo de referência para usar a API de hospedagem do XAML UWP em aplicativos WPF e Windows Forms. O código-fonte está disponível nos seguintes locais:

Observação

É altamente recomendável que você use os controles .NET XAML Island no kit de ferramentas da comunidade Windows em vez de usar a API de hospedagem de XAML UWP diretamente em aplicativos WPF e Windows Forms. Os links de exemplo WPF e Windows Forms neste artigo são apenas para fins ilustrativos.

Arquitetura da API

A API de hospedagem XAML da UWP inclui esses principais tipos de Windows Runtime e interfaces COM.

Tipo ou interface DESCRIÇÃO
WindowsXamlManager Essa classe representa a estrutura XAML UWP. Essa classe fornece um único método InitializeForCurrentThread estático que inicializa a estrutura XAML UWP no thread atual no aplicativo da área de trabalho.
DesktopWindowXamlSource Essa classe representa uma instância de conteúdo XAML UWP que você está hospedando em seu aplicativo da área de trabalho. O membro mais importante dessa classe é a propriedade Content . Você atribui essa propriedade a um Windows.UI.Xaml.UIElement que deseja hospedar. Esta classe também possui outros membros para controlar a navegação do foco do teclado dentro e fora das Ilhas XAML.
IDesktopWindowXamlSourceNative Essa interface COM fornece o método AttachToWindow, que você usa para anexar uma ilha XAML em seu aplicativo a um elemento de interface do usuário pai. Cada objeto DesktopWindowXamlSource implementa essa interface.
IDesktopWindowXamlSourceNative2 Essa interface COM fornece o método PreTranslateMessage , que permite que a estrutura XAML UWP processe certas mensagens do Windows corretamente. Cada objeto DesktopWindowXamlSource implementa essa interface.

O diagrama a seguir ilustra a hierarquia de objetos em uma Ilha XAML hospedada em um aplicativo da área de trabalho.

  • No nível base está o elemento de interface do usuário em seu aplicativo em que você deseja hospedar a Ilha XAML. Esse elemento de interface do usuário deve ter um HWND (identificador de janela). Exemplos de elementos de interface do usuário nos quais você pode hospedar uma Ilha XAML incluem um window para aplicativos da área de trabalho do C++, um System.Windows.Interop.HwndHost para aplicativos WPF e um System.Windows.Forms.Control para aplicativos Windows Forms.

  • No próximo nível está um objeto DesktopWindowXamlSource . Esse objeto fornece a infraestrutura para hospedar a Ilha XAML. Seu código é responsável por criar esse objeto e anexá-lo ao elemento de interface do usuário pai.

  • Quando você cria um DesktopWindowXamlSource, esse objeto cria automaticamente uma janela filho nativa para hospedar o controle XAML UWP. Essa janela filha nativa é abstraída principalmente do seu código, mas você pode acessar seu identificador (HWND), se necessário.

  • Por fim, no nível superior está o controle XAML UWP que você deseja hospedar em seu aplicativo da área de trabalho. Pode ser qualquer objeto UWP que deriva de Windows. UI. Xaml.UIElement, incluindo qualquer controle XAML UWP fornecido pelo SDK do Windows, bem como controles de usuário personalizados.

Arquitetura DesktopWindowXamlSource

Observação

Ao hospedar Ilhas XAML do UWP em um aplicativo de desktop, você pode ter várias árvores de conteúdo XAML em execução no mesmo thread simultaneamente. Para acessar o elemento raiz de uma árvore de conteúdo XAML em uma Ilha XAML e obter informações relacionadas sobre o contexto no qual ele está hospedado, use a classe XamlRoot. As APIs CoreWindow, ApplicationView e Window não fornecerão as informações corretas para ilhas XAML UWP. Para obter mais informações, consulte esta seção.

Práticas recomendadas

Ao usar a API de hospedagem XAML UWP, siga estas práticas recomendadas para cada thread que hospeda controles XAML UWP:

Resolução de problemas

Erro ao usar a API de hospedagem XAML UWP em um aplicativo UWP

Questão Resolução
Seu aplicativo recebe um COMException com a seguinte mensagem: "Não é possível ativar DesktopWindowXamlSource. Esse tipo não pode ser usado em um aplicativo UWP." ou "Não é possível ativar o WindowsXamlManager. Esse tipo não pode ser usado em um aplicativo UWP." Esse erro indica que você está tentando usar a API de hospedagem XAML UWP (especificamente, você está tentando instanciar os tipos DesktopWindowXamlSource ou WindowsXamlManager ) em um aplicativo UWP. A API de hospedagem XAML UWP destina-se apenas a ser usada em aplicativos de área de trabalho não UWP, como aplicativos de área de trabalho WPF, Windows Forms e C++.

Erro ao tentar usar os tipos WindowsXamlManager ou DesktopWindowXamlSource

Questão Resolução
Seu aplicativo recebe uma exceção com a seguinte mensagem: "WindowsXamlManager e DesktopWindowXamlSource têm suporte para aplicativos direcionados ao Windows versão 10.0.18226.0 e posterior. Verifique o manifesto do aplicativo ou o manifesto do pacote e verifique se a propriedade MaxTestedVersion está atualizada." Esse erro indica que seu aplicativo tentou usar os tipos WindowsXamlManager ou DesktopWindowXamlSource na API de hospedagem do XAML UWP, mas o sistema operacional não pode determinar se o aplicativo foi criado para direcionar Windows 10, versão 1903 ou posterior. A API de hospedagem XAML UWP foi introduzida pela primeira vez como uma versão prévia em uma versão anterior do Windows 10, mas só tem suporte a partir de Windows 10 versão 1903.

Para resolver esse problema, crie um pacote MSIX para o aplicativo e execute-o a partir do pacote, ou instale o pacote NuGet Microsoft.Toolkit.Win32.UI.SDK no seu projeto.

Erro ao anexar a uma janela em um thread diferente

Questão Resolução
Seu aplicativo recebe uma COMException com a seguinte mensagem: "Falha no método AttachToWindow porque o HWND especificado foi criado em um thread diferente". Esse erro indica que seu aplicativo chamou o método IDesktopWindowXamlSourceNative::AttachToWindow e passou o HWND de uma janela que foi criada em um thread distinto. Você deve passar o HWND de uma janela para este método se ela tiver sido criada no mesmo *thread* que o código a partir do qual você está chamando o método.

Erro ao anexar a uma janela em uma janela de nível superior diferente

Questão Resolução
Seu aplicativo recebe uma COMException com a seguinte mensagem: "O método AttachToWindow falhou porque o HWND especificado é descendente de uma janela de nível superior diferente do HWND que foi passado anteriormente para AttachToWindow no mesmo thread." Esse erro indica que seu aplicativo chamou o método IDesktopWindowXamlSourceNative::AttachToWindow e passou o HWND de uma janela que é descendente de um nível superior diferente do especificado em uma chamada anterior para esse método na mesma thread.

Depois que seu aplicativo chama AttachToWindow em um thread específico, todos os outros objetos DesktopWindowXamlSource no mesmo thread só podem ser anexados a janelas descendentes da mesma janela de nível superior que foi passada na primeira chamada para AttachToWindow. Quando todos os objetos DesktopWindowXamlSource são fechados para um thread específico, o próximo DesktopWindowXamlSource é então livre para anexar a qualquer janela novamente.

Para resolver esse problema, feche todos os objetos DesktopWindowXamlSource associados a outras janelas de nível superior neste thread ou crie um novo thread para este DesktopWindowXamlSource.