Condividi tramite


Procedura dettagliata: Creare un componente C# con controlli WinUI 3 e usarlo da un'app C++/WinRT che usa 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 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 altri dettagli sugli scenari supportati, vedere Creazione di componenti C#/WinRT nel repository GitHub per C#/WinRT.

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

Prerequisiti

Per questa procedura dettagliata sono richiesti gli strumenti e i componenti seguenti:

Creare il componente C#/WinRT con Windows App SDK

  1. Creare un nuovo progetto di libreria C# usando il modello Libreria di classi (WinUI 3 in Desktop) fornito da Windows App SDK. Per questa procedura dettagliata, il progetto di libreria è stato denominato WinUIComponentCs e la soluzione è stata denominata AuthoringWinUI.

    Lasciare deselezionata la casella Inserisci soluzione e progetto nella stessa directory. In caso contrario, la cartella packages per l'applicazione C++ nella sezione precedente interferirà con il progetto di libreria C#.

    Finestra di dialogo Nuova libreria

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

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

    i. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto e selezionare Gestisci pacchetti NuGet.

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

  4. Aggiungere le proprietà seguenti al progetto di libreria:

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • La proprietà CsWinRTComponent specifica che il progetto è un componente Windows Runtime, in modo che venga generato un file .winmd durante la compilazione del progetto.
  5. Aggiungere un controllo personalizzato o un controllo utente alla libreria. A tale scopo, 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 è stato aggiunto un nuovo Controllo utente (WinUI 3) che è stato denominato 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 file 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. 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 progetto WinUIComponentCs per generare un file .winmd per il componente.

Nota

È anche possibile creare un pacchetto NuGet come pacchetto NuGet per i consumer di app finali a cui fare riferimento. Per altri dettagli, vedere Creazione di componenti C#/WinRT nel repository GitHub per C#/WinRT.

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

I passaggi seguenti illustrano come utilizzare il componente creato dalla sezione precedente da un'applicazione C++/WinRT di Windows App SDK. L'utilizzo di un componente C#/WinRT da C++ richiede attualmente l'uso del modello App vuota in pacchetto (WinUI 3 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 in pacchetto che usano un progetto Creazione di pacchetti di applicazioni Windows (WAP) separato non è attualmente supportato. Vedere Creazione di componenti C#/WinRT nel repository GitHub per C#/WinRT per ottenere gli aggiornamenti più recenti sulle configurazioni di progetto supportate.

  1. Aggiungere un nuovo progetto di applicazione C++ di Windows App SDK alla soluzione. Fare clic con il pulsante destro del mouse sulla soluzione in Visual Studio e selezionare Aggiungi>Nuovo progetto. Selezionare il modello C++ App vuota, in pacchetto (WinUI 3 in Desktop) fornito da Windows App SDK. Per questa procedura dettagliata, l'app è stata denominata 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 progetto C++ e scegliere Aggiungi>Riferimento e selezionare il progetto WinUIComponentCs.

    Nota

    L'utilizzo di componenti come riferimento al pacchetto NuGet è supportato con alcune limitazioni. In particolare, i componenti con controlli utente personalizzati non possono attualmente essere utilizzati come riferimento al pacchetto NuGet.

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

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

    Nota

    Si è verificato un problema noto per cui il file Package.appxmanifest non viene visualizzato in Esplora soluzioni di Visual Studio. Per risolvere il problema, fare clic con il pulsante destro del mouse sul progetto C++, selezionare Scarica progetto e fare doppio clic sul progetto per aprire il file CppApp.vcxproj. Aggiungere la voce seguente al file di progetto e quindi ricaricare il progetto:

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

    In Package.appxmanifest aggiungere le registrazioni delle classi attivabili seguenti. Per attivare i tipi WinUI, è necessaria anche una voce aggiuntiva ActivatableClass per la classe WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider. Fare clic con il pulsante destro del mouse sul file Package.appxmanifest e selezionare 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 facendo clic con il pulsante destro del mouse su CppApp e selezionando Imposta come progetto di avvio. Impostare la configurazione della soluzione su x86. Prima della compilazione, potrebbe anche essere necessario ridestinare la soluzione per la compilazione con gli strumenti di compilazione di Visual Studio 2022. Fare clic con il pulsante destro del mouse sulla soluzione, selezionare Ridestina soluzionee aggiornare il set di strumenti della piattaforma a v143.

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

Problemi noti

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