Condividi tramite


Procedura dettagliata: creare un componente C# con controlli WinUI 3 e usarlo da un'app C++/WinRT che usa il Windows App SDK

C#/WinRT offre supporto per la creazione di componenti Windows Runtime, inclusi i tipi personalizzati WinUI e i controlli personalizzati. Questi componenti possono essere utilizzati da applicazioni C# o C++/WinRT che usano il Windows App SDK. È consigliabile usare C#/WinRT v1.6.4 o versione successiva per creare componenti di runtime con il supporto per la creazione di pacchetti NuGet.

Per altre informazioni sugli scenari supportati, vedere Authoring C#/WinRT components nel repository C#/WinRT GitHub.

Questa procedura dettagliata illustra come creare un componente C# con un controllo WinUI personalizzato e come usare tale componente da un'app C++/WinRT usando i modelli di Windows App SDK project.

Prerequisiti

Questa procedura dettagliata richiede gli strumenti e i componenti seguenti:

Creare il componente C#/WinRT usando il Windows App SDK

  1. Creare una nuova libreria C# project usando il modello Class Library (WinUI in Desktop) fornito dal Windows App SDK. Per questa procedura dettagliata, abbiamo denominato il progetto della libreria WinUIComponentCs e la soluzione AuthoringWinUI.

    Lasciare deselezionata la casella Posiziona soluzione e progetto nella stessa cartella (in caso contrario, la cartella packages per l'applicazione C++ nella sezione precedente finirà per interferire con il progetto della libreria C#).

    Finestra di dialogo Nuova libreria

  2. Eliminare il Class1.cs file incluso per impostazione predefinita.

  3. Installare il pacchetto NuGet Microsoft.Windows.CsWinRT più recente nel tuo progetto.

    i. In Solution Explorer fare clic con il pulsante destro del mouse sul nodo project e selezionare Gestisci pacchetti NuGet.

    ii. Cercare il pacchetto NuGet Microsoft.Windows.CsWinRT e installare la versione più recente.

  4. Aggiungi le proprietà seguenti al progetto della libreria:

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • La proprietà CsWinRTComponent specifica che il progetto è un componente Windows Runtime, in modo che un file .winmd venga generato quando si compila il progetto.
  5. Aggiungere un controllo personalizzato o un controllo utente alla libreria. Per fare clic con il pulsante destro del mouse sul progetto in Visual Studio, scegliere Aggiungi>Nuovo elemento e selezionare WinUI nel riquadro sinistro. Per questa procedura dettagliata, abbiamo aggiunto un nuovo controllo utente (WinUI) che abbiamo chiamato NameReporter.xaml. Il controllo utente NameReporter consente a un utente di immettere un nome e un cognome nel controllo TextBox appropriato e fare clic su un pulsante. Il controllo visualizza quindi una finestra di messaggio con il nome immesso dall'utente.

  6. Incollare il codice seguente nel NameReporter.xaml file:

    <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. Aggiungere il metodo seguente 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. È ora possibile compilare il WinUIComponentCs project per generare un file .winmd per il componente.

Annotazioni

È anche possibile creare il componente come pacchetto NuGet per i consumatori finali dell'app a cui fare riferimento. Per altri dettagli, vedere Authoring C#/WinRT components nel repository di Github C#/WinRT.

Fare riferimento al componente da un'app C++/WinRT Windows App SDK

I passaggi seguenti illustrano come utilizzare il componente creato dalla sezione precedente da un'applicazione Windows App SDK C++/WinRT. L'utilizzo di un componente C#/WinRT da C++ richiede attualmente l'uso del modello a progetto singolo Blank App, Packaged (WinUI in Desktop). Si noti che è anche possibile fare riferimento ai componenti C# dalle app in pacchetto C# senza registrazioni di classi.

L'utilizzo da app confezionate che usano un progetto di confezionamento applicazioni Windows (WAP) separato non è attualmente supportato. Vedi Configurazione di componenti C#/WinRT nel repository di GitHub C#/WinRT per gli aggiornamenti più recenti sulle configurazioni project supportate.

  1. Aggiungere un nuovo progetto di applicazione Windows App SDK C++ alla soluzione. Fare clic con il pulsante destro del mouse sulla soluzione in Visual Studio e selezionare Aggiungi>Nuovo Project. Selezionare il modello C++ Blank App, Packaged (WinUI in Desktop) fornito dal Windows App SDK. Per questa procedura dettagliata, l'app è stata chiamata CppApp.

  2. Aggiungere un riferimento al progetto dall'app C++ al componente C#. In Visual Studio fare clic con il pulsante destro del mouse sul project C++ e scegliere Aggiungi>Reference e selezionare il WinUIComponentCs project.

    Annotazioni

    L'utilizzo di componenti come riferimento a un pacchetto NuGet è supportato con alcune limitazioni. Ovvero, i componenti con controlli utente personalizzati non possono attualmente essere utilizzati come riferimento in un pacchetto NuGet.

  3. Nel file di intestazione dell'app pch.h aggiungere le righe seguenti:

    #include <winrt/WinUIComponentCs.h>
    #include <winrt/WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.h>
    
  4. Aprire il file manifesto del pacchetto, Package.appxmanifest.

    Annotazioni

    Esiste un problema noto per cui il file Package.appxmanifest non viene visualizzato in Visual Studio Solution Explorer. Per risolvere il problema, fare clic con il pulsante destro del mouse sul project C++, selezionare Unload Project e fare doppio clic sul project per aprire il file CppApp.vcxproj. Aggiungere la voce seguente al file project e quindi ricaricare il project:

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

    In Package.appxmanifest aggiungere le seguenti registrazioni della classe attivabili. È necessaria anche una voce aggiuntiva ActivatableClass per la classe WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider per attivare i tipi WinUI. Fare clic con il pulsante destro del mouse sul Package.appxmanifest file e scegliere Apri con>XML (Editor di testo) per modificare il file.

    <!--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. Apri il file MainWindow.xaml.

    i. Aggiungere un riferimento allo spazio dei nomi del componente nella parte superiore del file.

    xmlns:custom="using:WinUIComponentCs"
    

    ii. Aggiungere il controllo utente al codice XAML esistente.

    <StackPanel>
        ...
        <custom:NameReporter/>
    </StackPanel>
    
  6. Impostare CppApp come progetto di avvio: fare clic con il pulsante destro del mouse su CppApp e selezionare Imposta come progetto di avvio. Impostare la configurazione della soluzione su x86. Prima della compilazione, potrebbe anche essere necessario ridefinire la soluzione per la compilazione con gli strumenti di compilazione Visual Studio 2022. Fare clic con il pulsante destro del mouse sulla soluzione, selezionare Retarget solution e aggiornare il set di strumenti della piattaforma a v143.

  7. Compilare ed eseguire l'app per visualizzare il controllo NameReporter personalizzato.

Problemi noti

  • L'utilizzo di un componente C# come riferimento del progetto richiede che PublishReadyToRun sia impostato su False. Per altri dettagli, vedere Github Problema #1151.
  • Attualmente, l'utilizzo di un componente C# creato per AnyCPU da C++ è supportato solo dalle applicazioni x86. x64 e Arm64 generano un errore di runtime simile al seguente: %1 non è un'applicazione Win32 valida. Vedere Github Problema #1151 per altri dettagli.