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 de 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 de 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 Creación de componentes de C#/WinRT en el repositorio de GitHub de C#/WinRT.

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

Prerrequisitos

Este tutorial requiere las siguientes herramientas y componentes:

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

  1. Cree un nuevo proyecto de biblioteca de C# mediante la plantilla Biblioteca de clases (WinUI 3 en escritorio) proporcionada por el SDK de aplicaciones de Windows. En este recorrido paso a paso, hemos denominado el proyecto de biblioteca WinUIComponentCs, y la solución AuthoringWinUI.

    Deje desactivada la cuadro Colocar solución y proyecto en el mismo directorio (de lo contrario, la carpeta packages de 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 la versión más reciente del paquete NuGet Microsoft.Windows.CsWinRT en tu proyecto.

    i. En el 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 e instale la versión más reciente.

  4. Agregue las siguientes propiedades al proyecto de biblioteca:

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    
    • La CsWinRTComponent propiedad especifica que el proyecto es un componente de Windows Runtime para que se genere un .winmd archivo 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, se ha agregado un nuevo Control de usuario (WinUI 3) y se le ha asignado el nombre . 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 proyecto WinUIComponentCs para generar un .winmd archivo 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 creación de componentes de C#/WinRT en el repositorio de Github de C#/WinRT.

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

En los pasos siguientes se muestra cómo consumir el componente creado a partir de la sección anterior de una aplicación de Windows App SDK de C++/WinRT. Actualmente, consumir un componente de C#/WinRT desde C++ requiere utilizar la plantilla Aplicación en Blanco, empaquetada (WinUI 3 para escritorio). Tenga en cuenta que también se puede hacer referencia a los componentes de C# desde aplicaciones empaquetadas de C# sin registros de clases.

Actualmente no se admite el consumo de aplicaciones empaquetadas que usan un proyecto de empaquetado de aplicaciones de Windows (WAP) independiente. Consulte creación de componentes de C#/WinRT en el repositorio de GitHub de C#/WinRT para obtener las actualizaciones más recientes sobre las configuraciones de proyecto admitidas.

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

  2. Agregue una referencia de proyecto desde 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 Agregar>referencia 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 no aparece en el Package.appxmanifest Explorador de soluciones de Visual Studio. Para solucionarlo, haga clic con el botón derecho en el proyecto de C++, seleccione Descargar proyecto y haga doble clic en el proyecto para abrir el CppApp.vcxproj archivo. Agregue la entrada siguiente al archivo de proyecto y, a continuación, vuelva a cargar el proyecto:

    <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 2022. Haga clic con el botón derecho en la solución, seleccione Volver a obtener 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 El problema de Github 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 las aplicaciones producen un error en tiempo de ejecución similar a: %1 no es una aplicación Win32 válida. Consulte El problema de Github n.º 1151 para obtener más información.