Partilhar via


Passo a passo—Crie um componente C# com controles WinUI 3 e consuma-o de um aplicativo C++/WinRT que usa o SDK de aplicativos do Windows

C#/WinRT fornece suporte para a criação de componentes do Tempo de Execução do Windows, incluindo tipos personalizados WinUI e controles personalizados. Esses componentes podem ser consumidos de aplicativos C# ou C++/WinRT que usam o SDK de aplicativos do Windows. Recomendamos o uso de C#/WinRT v1.6.4 ou posterior para criar componentes de tempo de execução com suporte para empacotamento com NuGet.

Para obter mais detalhes sobre os cenários suportados, consulte Criação de componentes C#/WinRT no repositório GitHub 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 Windows App.

Pré-requisitos

Este passo a passo requer as seguintes ferramentas e componentes:

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

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

    Deixe a caixa de seleção "Place solution and project in the same directory" desmarcada (caso contrário, a pasta packages do aplicativo C++ na seção anterior acabará por interferir no projeto da biblioteca C#).

    Caixa de diálogo Nova biblioteca

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

  3. Instale o 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. Procure o pacote Microsoft.Windows.CsWinRT NuGet e instale a versão mais recente.

  4. Adicione as seguintes propriedades ao seu projeto de biblioteca:

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • A CsWinRTComponent propriedade especifica que seu projeto é um componente do Tempo de Execução do Windows para que um .winmd arquivo seja gerado quando você cria o projeto.
  5. Adicione um controle personalizado ou controle de usuário à sua 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 tutorial, adicionámos um novo Controlo de Utilizador (WinUI 3) e chamámos-lhe NameReporter.xaml. O controlo de utilizador NameReporter permite que um utilizador insira um nome e apelido na caixa de texto apropriada e clique num 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 os consumidores finais do aplicativo consultarem. Para obter mais detalhes, consulte Criação de componentes C#/WinRT no repositório Github C#/WinRT.

Referenciar o componente de uma aplicação C++/WinRT do Windows App SDK

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

Atualmente, não há suporte para o consumo de aplicativos empacotados que usam um projeto separado Windows Application Packaging (WAP). Consulte Criação de componentes C#/WinRT no repositório GitHub C#/WinRT para obter as atualizações mais recentes sobre configurações de projeto suportadas.

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

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

    Observação

    O consumo de componentes como uma referência de pacote NuGet é suportado 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 manifesto 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 contornar isso, clique com o botão direito do mouse em seu projeto C++, selecione Descarregar projeto e clique duas vezes no projeto para abrir o CppApp.vcxproj arquivo. Adicione a seguinte entrada ao arquivo de projeto e, em seguida, recarregue o projeto:

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

    No Package.appxmanifest, adicione os seguintes registos de classes ativáveis. Você também precisará de uma entrada adicional ActivatableClass para a classe WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider, a fim de 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 editá-lo.

    <!--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 ficheiro 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 rato em CppAppe selecione Definir como Projeto de Inicialização. Defina a configuração da solução como x86. Antes de compilar, você também pode precisar redirecionar 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 Redirecionar solução e atualize o conjunto de ferramentas da plataforma para v143.

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

Problemas conhecidos

  • O consumo de um componente C# como referência de projeto requer PublishReadyToRun ser definido como False. Consulte edição #1151 do Github para obter mais detalhes.
  • O consumo de um componente C# criado a AnyCPU partir de C++ é suportado apenas a partir de x86 aplicativos atualmente. x64 e Arm64 os aplicativos resultam em um erro de tempo de execução semelhante a: %1 não é um aplicativo Win32 válido. Consulte Github Issue #1151 para obter mais detalhes.