Condividi tramite


Procedura dettagliata: creare un componente C# con controlli WinUI 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 C#/WinRT.

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 progetto di Windows App SDK.

Prerequisiti

Questa procedura dettagliata richiede 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 in Desktop) fornito da Windows App SDK. Per questa procedura dettagliata, abbiamo chiamato il progetto di libreria WinUIComponentCs e la soluzione AuthoringWinUI.

    Lasciare deselezionata la casella Inserisci soluzione e progetto nella stessa directory . In caso contrario, la packages cartella per l'applicazione C++ nella sezione precedente finisce per interferire con il progetto di 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 progetto.

    i. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto e scegliere 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 CsWinRTComponent proprietà specifica che il progetto è un componente Windows Runtime in modo che venga generato un .winmd file quando si compila il 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, 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 progetto WinUIComponentCs per generare un .winmd file 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 Creazione di componenti C#/WinRT nel repository GitHub 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 Windows App SDK C++/WinRT. L'utilizzo di un componente C#/WinRT da C++ richiede attualmente l'uso del modello a progetto singolo "App vuota, pacchettizzato (WinUI in Desktop)". Si noti che è anche possibile fare riferimento ai componenti C# dalle app in pacchetto C# senza registrazioni di classi.

Il consumo da app confezionate che utilizzano un progetto WAP (Windows Application Packaging) separato non è attualmente supportato. Vedere Creazione di componenti C#/WinRT nel repository GitHub C#/WinRT per gli aggiornamenti più recenti nelle configurazioni di progetto 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 scegliere Aggiungi>nuovo progetto. Selezionare il modello App Vuota C++, Pacchettizzata (WinUI in Desktop) disponibile tramite 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 progetto C++ e scegliere Aggiungi>riferimento e selezionare il progetto WinUIComponentCs .

    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

    Si è verificato un problema noto per cui il Package.appxmanifest file non viene visualizzato in Esplora soluzioni di Visual Studio. Per risolvere il problema, fare clic con il pulsante destro del mouse sul progetto C++, scegliere Scarica progetto e fare doppio clic sul progetto per aprire il CppApp.vcxproj file. 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 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 scegliere 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 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 di progetto richiede che PublishReadyToRun sia impostato su False. Per altri dettagli , vedere Problema github n. 1151 .
  • Attualmente, l'utilizzo di un componente C# creato per AnyCPU da C++ è supportato solo dalle applicazioni x86. x64 e Arm64 le app generano un errore di runtime simile a: %1 non è un'applicazione Win32 valida. Per altri dettagli , vedere Problema github n. 1151 .