Procédure pas à pas : Créer un composant C# avec des contrôles WinUI 3 et le consommer à partir d’une application C++/WinRT qui utilise le SDK d’application Windows

C#/WinRT prend en charge la création de composants Windows Runtime, notamment les types personnalisés WinUI et les contrôles personnalisés. Ces composants peuvent être consommés à partir d’applications C# ou C++/WinRT qui utilisent le SDK d’application Windows. Nous vous recommandons d’utiliser C#/WinRT v1.6.4 ou version ultérieure pour créer des composants de runtime avec la prise en charge de l’empaquetage NuGet.

Pour plus d’informations sur les scénarios pris en charge, consultez Création de composants C#/WinRT dans le dépôt C#/WinRT de GitHub.

Cette procédure pas à pas montre comment créer un composant C# avec un contrôle WinUI 3 personnalisé et comment utiliser ce composant à partir d’une application C++/WinRT à l’aide des modèles de projet SDK d’application Windows.

Prérequis

Cette procédure pas à pas nécessite les composants et outils suivants :

Créer votre composant C#/WinRT à l’aide du SDK d’application Windows

  1. Créez un projet de bibliothèque C# à l’aide du modèle Bibliothèque de classes (WinUI 3 dans Desktop) fourni par le SDK d’application Windows. Pour cette procédure pas à pas, nous avons nommé le projet de bibliothèque WinUIComponentCs et la solution AuthoringWinUI.

    Laissez la case Placer la solution et le projet dans le même répertoire non cochée (sinon, le dossier packages de l’application C++ de la section précédente finira par interférer avec le projet de bibliothèque C#).

    New library dialog

  2. Supprimez le fichier Class1.cs inclus par défaut.

  3. Installez la dernière version du package NuGet Microsoft.Windows.CsWinRT dans votre projet.

    i. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet.

    ii. Recherchez le package NuGet appelé Microsoft.Windows.CsWinRT et installez la dernière version.

  4. Ajoutez les propriétés suivantes à votre projet de bibliothèque :

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • La propriété CsWinRTComponent spécifie que votre projet est un composant Windows Runtime, ce qui permet la génération d’un fichier .winmd lorsque vous créez le projet.
  5. Ajoutez un contrôle personnalisé ou un contrôle utilisateur à votre bibliothèque. Pour ce faire, cliquez avec le bouton droit sur votre projet dans Visual Studio, cliquez sur Ajouter>Nouvel élément, puis sélectionnez WinUI dans le volet gauche. Pour cette procédure pas à pas, nous avons ajouté un nouveau contrôle utilisateur (WinUI 3) et l’avons nommé NameReporter.xaml. Le contrôle utilisateur NameReporter permet à un utilisateur d’entrer un prénom et un nom dans le contrôle TextBox approprié, puis de cliquer sur un bouton. Le contrôle affiche ensuite une zone de message portant le nom entré par l’utilisateur.

  6. Collez le code suivant dans le fichier NameReporter.xaml :

    <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. Ajoutez la méthode suivante à 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. Vous pouvez maintenant créer le projet WinUIComponentCs pour générer un fichier .winmd pour le composant.

Notes

Vous pouvez également empaqueter le composant en tant que package NuGet pour que les consommateurs d’applications finaux puissent y faire référence. Pour plus d’informations, consultez Créer des composants C#/WinRT sur le dépôt Github C#/WinRT.

Référencer le composant à partir d’une application C++/WinRT du SDK d’application Windows

Les étapes suivantes montrent comment utiliser le composant créé à partir de la section précédente à partir d’une application C++/WinRT SDK du d’application Windows. L’utilisation d’un composant C#/WinRT à partir de C++ nécessite actuellement l’utilisation du modèle mono-projetBlank App, Packaged (WinUI 3 in Desktop). Notez que les composants C# peuvent également être référencés à partir d’applications empaquetées C# sans inscriptions de classes.

La consommation d’applications packagées qui utilisent un projet WAP (Windows Application Packaging) distinct n’est pas prise en charge actuellement. Consultez Création de composants C#/WinRT dans le dépôt C#/WinRT GitHub pour connaître les dernières mises à jour sur les configurations de projet prises en charge.

  1. Ajoutez un nouveau projet d’application C++ de SDK d’application Windows à votre solution. Cliquez avec le bouton droit sur votre solution dans Visual Studio, puis sélectionnez Ajouter>Nouveau projet. Sélectionnez le modèle C++ Blank App, Packaged (WinUI 3 in Desktop) fourni par le SDK d’application Windows. Pour cette procédure pas à pas, nous avons nommé l’application CppApp.

  2. Ajoutez une référence de projet à partir de l’application C++ au composant C#. Dans Visual Studio, cliquez avec le bouton droit sur le projet C++ et choisissez Ajouter>Référence, puis sélectionnez le projet WinUIComponentCs.

    Notes

    L’utilisation de composants en tant que référence de package NuGet est prise en charge avec certaines limitations. À savoir, les composants avec des contrôles utilisateur personnalisés ne peuvent actuellement pas être consommés en tant que référence de package NuGet.

  3. Dans le fichier d’en-tête pch.h de l’application, ajoutez les lignes suivantes :

    #include <winrt/WinUIComponentCs.h>
    #include <winrt/WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.h>
    
  4. Ouvrez le fichier manifeste du package : Package.appxmanifest.

    Notes

    Il existe un problème connu dans lequel le fichier Package.appxmanifest n’apparaît pas dans l’Explorateur de solutions Visual Studio. Pour contourner ce problème, cliquez avec le bouton droit sur votre projet C++, sélectionnez Décharger le projet, puis double-cliquez sur le projet pour ouvrir le fichier CppApp.vcxproj. Ajoutez l’entrée suivante au fichier de projet, puis rechargez le projet :

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

    Dans Package.appxmanifest, ajoutez les inscriptions de classes activables suivantes. Vous aurez également besoin d’une entrée ActivatableClass supplémentaire pour la classe WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider afin d’activer les types WinUI. Cliquez avec le bouton droit sur le fichier Package.appxmanifest et sélectionnez Ouvrir avec>XML (Éditeur de texte) pour modifier le fichier.

    <!--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. Ouvrez le fichier MainWindow.xaml .

    i. Ajoutez une référence à l’espace de noms du composant en haut du fichier.

    xmlns:custom="using:WinUIComponentCs"
    

    ii. Ajoutez le contrôle utilisateur au code XAML existant.

    <StackPanel>
        ...
        <custom:NameReporter/>
    </StackPanel>
    
  6. Définissez CppApp comme projet de démarrage : cliquez avec le bouton droit sur CppApp, puis sélectionnez Définir en tant que projet de démarrage. Définissez la configuration de la solution sur x86. Avant de commencer à créer, vous devrez peut-être également recibler votre solution pour créer avec les outils de génération Visual Studio 2022. Cliquez avec le bouton droit sur la solution, sélectionnez Recibler la solution et mettez à niveau l’ensemble d’outils de plateforme vers la version 143.

  7. Générez et exécutez l’application pour afficher le contrôle NameReporter personnalisé.

Problèmes connus

  • L’utilisation d’un composant C# comme référence de projet nécessite que PublishReadyToRun soit défini sur False. Pour plus d’informations, consultez le problème Github 1151.
  • L’utilisation d’un composant C# créé pour AnyCPU à partir de C++ est prise en charge uniquement à partir d’applications x86 pour l’instant. Les applications x64 et Arm64 entraînent une erreur d’exécution similaire à celle-ci : %1 n’est pas une application Win32 valide. Pour plus d’informations, consultez le problème Github 1151.