Compartir a través de


Tutorial: Crear un componente de C# con controles WinUI 3 y consumirlo desde una aplicación de C++/WinRT que usa el SDK de Aplicaciones para Windows

C#/WinRT proporciona compatibilidad con la creación de componentes de Windows Runtime, incluidos los tipos personalizados de WinUI y los controles personalizados. Estos componentes se pueden consumir desde aplicaciones de C# o C++/WinRT que usan el SDK de Aplicaciones para Windows. Se recomienda usar C#/WinRT v1.6.4 o posterior para crear componentes en tiempo de ejecución con compatibilidad con el empaquetado de NuGet.

Para obtener más información sobre los escenarios admitidos, consulte Authoring C#/WinRT components en el repositorio de GitHub de C#/WinRT.

En este tutorial se muestra cómo crear un componente de C# con un control WinUI personalizado y cómo consumir ese componente desde una aplicación de C++/WinRT mediante las plantillas de proyecto de SDK de Aplicaciones para Windows.

Prerrequisitos

Este tutorial requiere las siguientes herramientas y componentes:

Creación del componente de C#/WinRT mediante el SDK de Aplicaciones para Windows

  1. Cree un nuevo proyecto de biblioteca de C# con la plantilla Class Library (WinUI in Desktop) proporcionada por el SDK de Aplicaciones para Windows. Para esta guía, hemos denominado la biblioteca del proyecto WinUIComponentCs y la solución AuthoringWinUI.

    Deje la casilla Ubicar solución y proyecto en el mismo directorio sin marcar (de lo contrario, la carpeta packages para la aplicación de C++ en la sección anterior terminará interfiriendo con el proyecto de biblioteca de C#).

    Nueva biblioteca cuadro de diálogo

  2. Elimine el Class1.cs archivo que se incluye de forma predeterminada.

  3. Instale el paquete NuGet Microsoft.Windows.CsWinRT más reciente en tu proyecto.

    i. En Explorador de soluciones, haga clic con el botón derecho en el nodo del proyecto y seleccione Administrar paquetes NuGet.

    ii. Busque el paquete NuGet Microsoft.Windows.CsWinRT y instale la versión más reciente.

  4. Agregue las siguientes propiedades a su proyecto de biblioteca:

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • La propiedad CsWinRTComponent especifica que su proyecto es un componente de Windows Runtime, de modo que se genere un archivo .winmd al compilar el proyecto.
  5. Agregue un control personalizado o un control de usuario a la biblioteca. Para ello, haga clic con el botón derecho en el proyecto en Visual Studio, haga clic en Agregar>Nuevo elemento y seleccione WinUI en el panel izquierdo. En este tutorial, agregamos un nuevo control de usuario (WinUI) y le dimos el nombre NameReporter.xaml. El control de usuario NameReporter permite a un usuario escribir un nombre y apellido en el control TextBox adecuado y hacer clic en un botón. A continuación, el control muestra un cuadro de mensaje con el nombre especificado por el usuario.

  6. Pegue el código siguiente en el NameReporter.xaml archivo:

    <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. Agregue el método siguiente 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. Ahora puede compilar el WinUIComponentCs proyecto para generar un .winmd para el componente.

Nota:

También puede empaquetar el componente como un paquete NuGet para que los consumidores finales de la aplicación hagan referencia. Para obtener más información, consulte Authoring C#/WinRT components en el repositorio de GitHub de C#/WinRT.

Hacer referencia al componente desde una aplicación de C++/WinRT de SDK de Aplicaciones para Windows

En los pasos siguientes se muestra cómo consumir el componente creado a partir de la sección anterior de una aplicación de SDK de Aplicaciones para Windows de C++/WinRT. El consumo de un componente de C#/WinRT de C++ actualmente requiere el uso de la plantilla Aplicación en blanco (empaquetada) de WinUI de un solo proyecto. Tenga en cuenta que también se puede hacer referencia a los componentes de C# desde aplicaciones empaquetadas de C# sin registros de clases.

El consumo desde aplicaciones empaquetadas que utilizan un proyecto independiente Windows Application Packaging (WAP) no está actualmente soportado. Consulte los componentes de Authoring C#/WinRT en el repositorio de GitHub de C#/WinRT para obtener las actualizaciones más recientes en las configuraciones de proyecto admitidas.

  1. Agregue un nuevo proyecto de aplicación de SDK de Aplicaciones para Windows de C++ a la solución. Haga clic con el botón derecho en la solución en Visual Studio y seleccione Agregar>Nuevo Project. Seleccione la plantilla WinUI Blank App (Empaquetado) de C++ proporcionada por SDK de Aplicaciones para Windows. En este tutorial, llamamos a la aplicación CppApp.

  2. Agregue una referencia de proyecto de la aplicación de C++ al componente de C#. En Visual Studio, haga clic con el botón derecho en el proyecto de C++ y elija Add>Reference y seleccione el proyecto WinUIComponentCs.

    Nota:

    El consumo de componentes como referencia de paquete NuGet se admite con algunas limitaciones. Es decir, los componentes con controles de usuario personalizados no se pueden consumir actualmente como referencia de paquete NuGet.

  3. En el archivo de encabezado de pch.h la aplicación, agregue las siguientes líneas:

    #include <winrt/WinUIComponentCs.h>
    #include <winrt/WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.h>
    
  4. Abra el archivo de manifiesto del paquete Package.appxmanifest.

    Nota:

    Hay un problema conocido por el que el archivo Package.appxmanifest no aparece en Visual Studio Explorador de soluciones. Para solucionarlo, haga clic con el botón derecho en el project de C++, seleccione Unload Project y haga doble clic en el project para abrir el archivo CppApp.vcxproj. Agregue la entrada siguiente al archivo project y, a continuación, vuelva a cargar el project:

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

    En Package.appxmanifest, agregue los siguientes registros de clases activables. También necesitarás una entrada adicional de ActivatableClass para la clase WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider con el fin de activar los tipos de WinUI. Haga clic con el botón derecho en el Package.appxmanifest archivo y seleccione Abrir con>XML (Editor de texto) para editar el archivo.

    <!--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 el archivo MainWindow.xaml.

    i. Agregue una referencia al espacio de nombres del componente en la parte superior del archivo.

    xmlns:custom="using:WinUIComponentCs"
    

    ii. Agregue el control de usuario al código XAML existente.

    <StackPanel>
        ...
        <custom:NameReporter/>
    </StackPanel>
    
  6. Establezca CppApp como proyecto de inicio, haga clic con el botón derecho en CppApp y seleccione Establecer como proyecto de inicio. Establezca la configuración de la solución en x86. Antes de compilar, es posible que también tenga que volver a configurar la solución para compilar con las herramientas de compilación de Visual Studio 2026. Haga clic con el botón derecho en la solución, seleccione Retarget de la solución y actualice el conjunto de herramientas de plataforma a v143.

  7. Compile y ejecute la aplicación para ver el control personalizado NameReporter.

Problemas conocidos

  • El consumo de un componente de C# como referencia de proyecto requiere que PublishReadyToRun se establezca en False. Consulte GitHub problema n.º 1151 para obtener más información.
  • El consumo de un componente de C# creado para AnyCPU desde C++ solo se admite actualmente desde x86 aplicaciones. x64 y Arm64 aplicaciones producen un error en tiempo de ejecución similar al siguiente: %1 no es una aplicación Win32 válida. consulte GitHub problema #1093 para obtener más detalles.