Compartilhar via


Passo a passo—Criar um componente C# com controles WinUI 3 e utilizá-lo em um aplicativo C++/WinRT que usa o Windows App SDK

O C#/WinRT dá suporte à criação de componentes do Windows Runtime, incluindo tipos personalizados do WinUI e controles personalizados. Esses componentes podem ser consumidos de aplicativos C# ou C++/WinRT que usam o SDK do Aplicativo do Windows. É recomendável usar o C#/WinRT v1.6.4 ou posterior para criar componentes de runtime com suporte ao empacotamento NuGet.

Para obter mais detalhes sobre os cenários com suporte, consulte criar componentes C#/WinRT no repositório GitHub do C#/WinRT.

Este passo a passo demonstra como criar um componente C# com um controle WinUI 3 personalizado e como consumir esse componente de um aplicativo C++/WinRT usando os modelos de projeto do SDK do Aplicativo Windows.

Pré-requisitos

Este passo a passo requer as seguintes ferramentas e componentes:

Criar seu componente C#/WinRT usando o SDK do Aplicativo do Windows

  1. Crie um novo projeto de biblioteca C# usando o modelo Biblioteca de Classes (WinUI 3 na Área de Trabalho) fornecido pelo Windows App SDK. Para este passo a passo, nomeamos o projeto de biblioteca WinUIComponentCs e a solução AuthoringWinUI.

    Deixe a opção "Colocar solução e projeto no mesmo diretório" desmarcada (caso contrário, a pasta packages para o aplicativo C++ na seção anterior acabará interferindo no projeto da biblioteca C#).

    nova de diálogo da biblioteca

  2. Exclua o Class1.cs arquivo incluído por padrão.

  3. Instale a pacote NuGet Microsoft.Windows.CsWinRT mais recente em seu projeto.

    i. No Gerenciador de Soluções, clique com o botão direito do mouse no nó do projeto e selecione Gerenciar Pacotes NuGet.

    ii. Pesquise o pacote NuGet Microsoft.Windows.CsWinRT e instale a versão mais recente.

  4. Adicione as seguintes propriedades ao projeto de biblioteca:

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • A CsWinRTComponent propriedade especifica que seu projeto é um componente do Windows Runtime para que um .winmd arquivo seja gerado quando você compilar o projeto.
  5. Adicione um controle personalizado ou controle de usuário à biblioteca. Para fazer isso, clique com o botão direito do mouse em seu projeto no Visual Studio, clique em Adicionar>Novo Item e selecione WinUI no painel esquerdo. Para este passo a passo, adicionamos um novo Controle de Usuário (WinUI 3) e nomeamos NameReporter.xaml. O controle de usuário NameReporter permite que um usuário insira um nome e sobrenome no controle TextBox apropriado e clique em um botão. Em seguida, o controle exibe uma caixa de mensagem com o nome que o usuário inseriu.

  6. Cole o seguinte código no NameReporter.xaml arquivo:

    <UserControl
    x:Class="WinUIComponentCs.NameReporter"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUIComponentCs"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    
        <StackPanel HorizontalAlignment="Center">
            <StackPanel.Resources>
                <Style x:Key="BasicTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BodyTextBlockStyle}">
                    <Setter Property="Margin" Value="10,10,10,10"/>
                </Style>
            </StackPanel.Resources>
    
            <TextBlock Text="Enter your name." Margin="0,0,0,10"/>
            <StackPanel Orientation="Horizontal" Margin="0,0,0,10">
                <TextBlock Style="{StaticResource BasicTextStyle}">
                    First Name:
                </TextBlock>
                <TextBox Name="firstName" />
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="0,0,0,10">
                <TextBlock Style="{StaticResource BasicTextStyle}">
                    Last Name:
                </TextBlock>
                <TextBox Name="lastName" />
            </StackPanel>
            <Button Content="Submit" Click="Button_Click" Margin="0,0,0,10"/>
            <TextBlock Name="result" Style="{StaticResource BasicTextStyle}" Margin="0,0,0,10"/>
        </StackPanel>
    </UserControl>
    
  7. Adicione o seguinte método a NameReporter.xaml.cs:

    using System.Text;
    ...
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        StringBuilder displayText = new StringBuilder("Hello, ");
        displayText.AppendFormat("{0} {1}.", firstName.Text, lastName.Text);
        result.Text = displayText.ToString();
    }
    
  8. Agora você pode criar o projeto WinUIComponentCs para gerar um .winmd arquivo para o componente.

Observação

Você também pode empacotar o componente como um pacote NuGet para que os consumidores do aplicativo final façam referência. Para obter mais detalhes, consulte criação de componentes C#/WinRT no repositório Github do C#/WinRT.

Referenciar o componente de um aplicativo do SDK de Aplicativos do Windows C++/WinRT

As etapas a seguir mostram como consumir o componente criado na seção anterior de um aplicativo Windows App SDK em C++/WinRT. Atualmente, consumir um componente C#/WinRT a partir de C++ requer o uso do modelo de aplicativo em branco, empacotado em projeto único (WinUI 3 na Área de Trabalho). Observe que os componentes C# também podem ser referenciados de aplicativos empacotados em C# sem registros de classe.

No momento, não há suporte para o consumo de aplicativos empacotados que usam um projeto de Empacotamento de Aplicativos do Windows (WAP) separado. Consulte a criação de componentes C#/WinRT no repositório GitHub do C#/WinRT para obter as atualizações mais recentes sobre as configurações de projeto com suporte.

  1. Adicione um novo projeto de aplicativo do SDK de Aplicativo do Windows C++ à sua solução. Clique com o botão direito do mouse na solução no Visual Studio e selecione Adicionar>Novo Projeto. Selecione o modelo de C++ Aplicativo em Branco, Empacotado (WinUI 3 na Área de Trabalho) fornecido pelo SDK do Aplicativo do Windows. Para este passo a passo, nomeamos o aplicativo CppApp.

  2. Adicione uma referência de projeto do aplicativo C++ ao componente C#. No Visual Studio, clique com o botão direito do mouse no projeto C++ e escolha Adicionar>Referênciae selecione o projeto WinUIComponentCs.

    Observação

    O consumo de componentes como referência de pacote NuGet é suportado, mas com algumas limitações. Ou seja, componentes com controles de usuário personalizados não podem ser consumidos atualmente como uma referência de pacote NuGet.

  3. No arquivo de cabeçalho do pch.h aplicativo, adicione as seguintes linhas:

    #include <winrt/WinUIComponentCs.h>
    #include <winrt/WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.h>
    
  4. Abra o arquivo de manifest do pacote, Package.appxmanifest.

    Observação

    Há um problema conhecido em que o Package.appxmanifest arquivo não aparece no Gerenciador de Soluções do Visual Studio. Para solucionar isso, clique com o botão direito do mouse no projeto C++, selecione Descarregar Projetoe clique duas vezes no projeto para abrir o arquivo CppApp.vcxproj. Adicione a seguinte entrada ao arquivo de projeto e recarregue o projeto:

    <ItemGroup>
        <AppxManifest Include="Package.appxmanifest">
        <SubType>Designer</SubType>
        </AppxManifest>
    </ItemGroup>
    

    Em Package.appxmanifest, adicione os seguintes registros de classe ativáveis. Você também precisará de uma entrada de ActivatableClass adicional para a classe WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider para ativar os tipos WinUI. Clique com o botão direito do Package.appxmanifest mouse no arquivo e selecione Abrir com>XML (Editor de Texto) para editar o arquivo.

    <!--In order to host the C# component from C++, you must add the following Extension group and list the activatable classes-->
    <Extensions>
        <Extension Category="windows.activatableClass.inProcessServer">
            <InProcessServer>
                <Path>WinRT.Host.dll</Path>
                <ActivatableClass ActivatableClassId="WinUIComponentCs.NameReporter" ThreadingModel="both" />
                <ActivatableClass ActivatableClassId="WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider" ThreadingModel="both" />
            </InProcessServer>
        </Extension>
    </Extensions>
    
  5. Abra o arquivo MainWindow.xaml.

    i. Adicione uma referência ao namespace do componente na parte superior do arquivo.

    xmlns:custom="using:WinUIComponentCs"
    

    ii. Adicione o controle de usuário ao código XAML existente.

    <StackPanel>
        ...
        <custom:NameReporter/>
    </StackPanel>
    
  6. Defina CppApp como o projeto de inicialização—clique com o botão direito do mouse em CppApp, e selecione Definir como Projeto de Inicialização. Defina a configuração da solução como x86. Antes de compilar, talvez você também precise reconfigurar sua solução para compilar com as ferramentas de compilação do Visual Studio 2022. Clique com o botão direito do mouse na solução, selecione Retarget solution, e atualize o Platform Toolset para v143.

  7. Crie e execute o aplicativo para ver o controle personalizado NameReporter.

Problemas conhecidos

  • Consumir um componente C# como referência de projeto requer que PublishReadyToRun sejam definidos como False. Consulte o problema do Github nº 1151 para obter mais detalhes.
  • O consumo de um componente C# criado para AnyCPU a partir do C++ tem suporte apenas por aplicativos x86 atualmente. x64 e Arm64 aplicativos resultam em um erro de runtime semelhante a: %1 não é um aplicativo Win32 válido. Consulte o Problema do Github nº 1151 para obter mais detalhes.