C#/WinRT 支持创作 Windows 运行时组件,包括 WinUI 自定义类型和自定义控件。 可以从使用 Windows 应用 SDK 的 C# 或 C++/WinRT 应用程序使用这些组件。 建议使用 C#/WinRT v1.6.4 或更高版本创作具有 NuGet 打包支持的运行时组件。
有关支持场景的更多详细信息,请参阅 C#/WinRT GitHub 存储库中的 编写 C#/WinRT 组件。
本演练演示如何使用自定义 WinUI 3 控件编写 C# 组件,以及如何通过 Windows 应用 SDK 项目模板从 C++/WinRT 应用调用该组件。
先决条件
本演练需要以下工具和组件:
- Visual Studio 2022
- .NET 6.0 SDK
- Windows 应用 SDK VSIX(稳定通道中的 1.1)
使用 Windows 应用 SDK 创作 C#/WinRT 组件
使用 Windows 应用 SDK 提供的 类库 (WinUI 3 in Desktop) 模板创建新的 C# 库项目。 在本演练中,我们将库项目命名为 WinUIComponentCs,将解决方案命名为 AuthoringWinUI。
请保持「将解决方案和项目放在同一目录中」 选项框未选中(否则,上一部分中针对 C++ 应用程序的
packages文件夹将最终干扰 C# 库项目)。
Class1.cs删除默认包含的文件。在项目中安装最新的 Microsoft.Windows.CsWinRT NuGet 包。
一. 在解决方案资源管理器中,右键单击项目节点,然后选择“ 管理 NuGet 包”。
二. 搜索 Microsoft.Windows.CsWinRT NuGet 包并安装最新版本。
将以下属性添加到库项目:
<PropertyGroup> <CsWinRTComponent>true</CsWinRTComponent> </PropertyGroup>- 该
CsWinRTComponent属性指定项目是 Windows 运行时组件,.winmd以便在生成项目时生成文件。
- 该
将自定义控件或用户控件添加到库中。 为此,请在 Visual Studio 中右键单击项目,单击“ 添加新>项”,然后在左窗格中选择 “WinUI ”。 在本演练中,我们添加了一个新的 用户控件(WinUI 3), 并将其命名
NameReporter.xaml。 NameReporter 用户控件允许用户在相应的 TextBox 控件中输入名字和姓氏,然后单击按钮。 然后,该控件会显示一个消息框,其中包含用户输入的名称。将以下代码粘贴到
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>将以下方法添加到
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(); }现在可以生成 WinUIComponentCs 项目,为组件生成
.winmd文件。
注释
还可以将组件打包为 NuGet 包,供最终用户引用。 有关详细信息,请参阅 C#/WinRT Github 存储库上的 编写 C#/WinRT 组件。
从 Windows 应用 SDK C++/WinRT 应用中调用组件
以下步骤演示如何使用 C++/WinRT Windows App SDK 应用程序中从上一部分创建的组件。 使用来自C++的 C#/WinRT 组件当前需要使用单项目 空白应用、打包(桌面中的 WinUI 3) 模板。 请注意,还可以从没有类注册的 C# 打包应用引用 C# 组件。
目前不支持从使用单独 Windows 应用程序打包(WAP) 项目的应用程序包进行的消费。 有关支持的项目配置的最新更新,请参阅 C#/WinRT GitHub 存储库中的 编写 C#/WinRT 组件。
向解决方案添加新C++ Windows 应用 SDK 应用程序项目。 在 Visual Studio 中右键单击您的解决方案,然后选择 添加>新项目。 选择 Windows 应用 SDK 提供的C++空白应用打包(桌面中的 WinUI 3) 模板。 在本演练中,这个应用被命名为 CppApp。
将C++应用中的项目引用添加到 C# 组件。 在 Visual Studio 中,右键单击C++项目,然后选择 “添加>引用”,然后选择 WinUIComponentCs 项目。
注释
支持将组件用作 NuGet 包引用,但存在一些限制。 也就是说,具有自定义用户控件的组件当前不能用作 NuGet 包引用。
在应用的
pch.h头文件中,添加以下行:#include <winrt/WinUIComponentCs.h> #include <winrt/WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.h>打开包清单文件,
Package.appxmanifest。注释
存在一个已知问题
Package.appxmanifest,即该文件不会出现在 Visual Studio 解决方案资源管理器中。 若要解决此问题,请右键单击C++项目,选择“ 卸载项目”,然后双击项目以打开CppApp.vcxproj该文件。 将以下条目添加到项目文件,然后重新加载项目:<ItemGroup> <AppxManifest Include="Package.appxmanifest"> <SubType>Designer</SubType> </AppxManifest> </ItemGroup>在
Package.appxmanifest中,添加以下可激活类注册。 还需要为ActivatableClass类提供额外的 条目才能激活 WinUI 类型。 右键单击Package.appxmanifest文件,然后选择 使用>XML(文本编辑器) 打开,以便编辑该文件。<!--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>打开
MainWindow.xaml文件。一. 在文件的顶部添加对组件的命名空间的引用。
xmlns:custom="using:WinUIComponentCs"二. 将用户控件添加到现有 XAML 代码。
<StackPanel> ... <custom:NameReporter/> </StackPanel>将 CppApp 设置为启动项目 - 右键单击 CppApp,然后选择“ 设置为启动项目”。 将解决方案配置设置为
x86. 在生成之前,可能还需要重新定位解决方案,以便使用 Visual Studio 2022 生成工具进行生成。 右键单击解决方案,选择 “重定目标”解决方案,然后将平台工具集升级到 v143。生成并运行应用以查看自定义 NameReporter 控件。
已知问题
- 使用 C# 组件作为项目引用需要
PublishReadyToRun设置为False。 有关更多详细信息 ,请参阅 Github 问题 #1151 。 - 目前仅支持从 C++ 调用专为
AnyCPU构建的 C# 组件,这种支持仅限于x86应用程序。x64和Arm64应用导致运行时错误类似于: %1 不是有效的 Win32 应用程序。 有关更多详细信息 ,请参阅 Github 问题 #1151 。