Partilhar via


Guia—Crie um componente C# com controlos do WinUI 3 e consuma-o a partir de uma aplicação C++/WinRT que utilize o Windows App SDK

O C#/WinRT oferece suporte para a autoria de componentes do Windows Runtime, incluindo tipos personalizados WinUI e controlos personalizados. Estes componentes podem ser consumidos tanto a partir de aplicações C# como C++/WinRT que utilizam o Windows App SDK. 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 mais detalhes sobre os cenários suportados, consulte Authoring C#/WinRT components no repositório de GitHub C#/WinRT.

Esta explicação demonstra como criar um componente C# com um controlo WinUI personalizado e como consumir esse componente a partir de uma aplicação C++/WinRT, usando os modelos Windows App SDK project.

Pré-requisitos

Este passo a passo requer as seguintes ferramentas e componentes:

Crie o seu componente C#/WinRT usando o Windows App SDK

  1. Crie uma nova biblioteca C# project usando o modelo Class Library (WinUI in Desktop) fornecido pelo Windows App SDK. Para este guia passo a passo, nomeámos o projeto da biblioteca WinUIComponentCs e a solução AuthoringWinUI.

    Deixe a caixa Colocar solução e projeto no mesmo diretório desmarcada (caso contrário, a pasta packages da aplicação C++ na seção anterior acabará por interferir com o 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 mais recente Microsoft.Windows.CsWinRT no seu projeto.

    i) Em Solution Explorer, clique com o botão direito no nó do projeto e selecione Gerir Pacotes NuGet.

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

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

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • A propriedade CsWinRTComponent especifica que o seu projeto é um componente Windows Runtime para que um ficheiro .winmd seja gerado quando constrói o projeto.
  5. Adicione um controle personalizado ou controle de usuário à sua biblioteca. To do isto, clique com o botão direito no seu project em Visual Studio, clique em Adicionar>Novo Item e selecione WinUI no painel esquerdo. Para este guia, adicionámos um novo Controlo do Utilizador (WinUI) e chamámo-lo 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 pode compilar o WinUIComponentCs project para gerar um ficheiro .winmd para o componente.

Observação

Você também pode empacotar o componente como um pacote NuGet para os consumidores finais do aplicativo consultarem. Para mais detalhes, consulte Authoring C#/WinRT components no repositório de Github C#/WinRT.

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

Os passos seguintes mostram como consumir o componente criado a partir da secção anterior a partir de uma aplicação Windows App SDK C++/WinRT. Consumir um componente C#/WinRT a partir de C++ atualmente requer o uso do modelo de projeto único Blank App, Packaged (WinUI in Desktop). Observe que os componentes do C# também podem ser referenciados a partir de aplicativos empacotados em C# sem registros de classe.

O consumo de aplicações empacotadas que utilizam um projeto Windows Application Packaging (WAP) separado não é atualmente suportada. Consulte Authoring C#/WinRT components no repositório GitHub C#/WinRT para obter as atualizações mais recentes sobre configurações de projetos suportadas.

  1. Adicione um novo project de aplicação C++ para Windows App SDK à sua solução. Clique com o botão direito na sua solução em Visual Studio e selecione Adicionar>Novo Project. Selecione o modelo de aplicação C++ Blank App, Packaged (WinUI in Desktop) fornecido pelo Windows App SDK. Para este tutorial, nomeamos a aplicação CppApp.

  2. Adicione uma referência de projeto da aplicação C++ ao componente C#. No Visual Studio, clique com o botão direito no projeto C++ e escolha Add>Reference, 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 ficheiro Package.appxmanifest não aparece no Visual Studio Solution Explorer. Para contornar isso, clique com o botão direito no seu project C++, selecione Descarregar Project e clique duas vezes no project para abrir o ficheiro CppApp.vcxproj. Adicione a seguinte entrada ao ficheiro do project e depois recarregue o project:

    <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 arranque — clique com o botão direito em CppApp e selecione Definir como Projeto de Arranque. Defina a configuração da solução como x86. Antes de compilar, poderá também precisar de redirecionar a 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

  • Consumir um componente C# como referência de projeto requer que PublishReadyToRun seja definido para False. Ver Github Edição #1151 para mais detalhes.
  • O consumo de um componente C# criado para AnyCPU a partir de C++ é suportado apenas a partir de x86 aplicações atualmente. x64 e Arm64 aplicações resultam num erro de execução semelhante a: %1 não é uma aplicação válida do Win32. Ver Github Edição #1151 para mais detalhes.