逐步解說—使用 WinUI 3 控制項建立 C# 元件並從使用 Windows 應用程式 SDK 的 C++/WinRT 應用程式加以取用
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 套件安裝到您的專案中。
i. 在 [方案總管] 中,以滑鼠右鍵按一下專案節點,然後選取 [管理 NuGet 套件]。
ii. 搜尋 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 應用程式 SDK 應用程式取用上一節建立的元件。 要從 C++ 取用 C#/WinRT 元件目前需要使用單一專案已封裝的空白應用程式 (WinUI 3 in Desktop) 範本。 請注意,C# 元件也可從沒有類別註冊的 C# 封裝應用程式加以參考。
目前不支援從使用個別 Windows 應用程式封裝 (WAP) 專案的已封裝應用程式取用。 如需所支援專案組態的最新更新,請參閱 C#/WinRT GitHub 存放庫中的撰寫 C#/WinRT 元件。
將新的 C++ Windows 應用程式 SDK 應用程式專案新增至您的方案。 以滑鼠右鍵按一下您在 Visual Studio 中的方案,然後選取 [新增]>[新增專案]。 選取 Windows 應用程式 SDK 所提供的 C++ 已封裝的空白應用程式 (WinUI 3 in Desktop) 範本。 在本逐步解說中,我們將應用程式命名為 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
中,新增下列可啟用類別註冊。 針對 WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider 類別,您還需要額外的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
檔案。i. 在檔案頂端新增元件命名空間的參考。
xmlns:custom="using:WinUIComponentCs"
ii. 將使用者控制項新增至現有的 XAML 程式碼。
<StackPanel> ... <custom:NameReporter/> </StackPanel>
將 CppApp 設定為啟始專案—以滑鼠右鍵按一下 [CppApp],然後選取 [設定為啟始專案]。 將方案組態設定為
x86
。 在建置之前,您可能還需要重定方案,以使用 Visual Studio 2022 建置工具進行建置。 以滑鼠右鍵按一下方案,選取 [重定方案],然後將平台工具組升級至 v143。建置並執行應用程式以查看自訂 NameReporter 控制項。
已知問題
- 要以專案參考的形式取用 C# 元件需要將
PublishReadyToRun
設定為False
。 如需詳細資訊,請參閱 Github 問題 #1151。 - 目前僅支援透過
x86
應用程式從 C++ 取用針對AnyCPU
所建置的 C# 元件。x64
和Arm64
應用程式會導致類似下面的執行階段錯誤:%1 不是有效的 Win32 應用程式。如需詳細資訊,請參閱 Github 問題 #1151。