チュートリアル — WinUI 3 コントロールを使用して C# コンポーネントを作成し、Windows App SDK を使用する C++/WinRT アプリから使用する
C#/WinRT では、WinUI のカスタム型やカスタム コントロールなど、Windows ランタイム コンポーネントの作成がサポートされています。 これらのコンポーネントは、Windows App SDKを使う C# または C++/WinRT アプリケーションから使用できます。 C#/WinRT v1.6.4 以降を使って、NuGet のパッケージ化をサポートするランタイム コンポーネントを作成することをお勧めします。
サポートされるシナリオについて詳しくは、C#/WinRT GitHub リポジトリの「C#/WinRT コンポーネントの作成」をご覧ください。
このチュートリアルでは、カスタム WinUI 3 コントロールを使って C# コンポーネントを作成する方法と、Windows App SDK プロジェクト テンプレートを使って C++/WinRT アプリからそのコンポーネントを利用する方法を示します。
前提条件
このチュートリアルでは、次のツールとコンポーネントが必要です。
- Visual Studio 2022
- .NET 6.0 SDK
- Windows App SDK VSIX (安定チャネルからの 1.1)
Windows App SDK を使用して C#/WinRT コンポーネントを作成する
Windows App SDK によって提供されるクラス ライブラリ (デスクトップでは WinUI 3) テンプレートを使って、新しい 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 App SDK C++/WinRT アプリからコンポーネントを参照する
次の手順では、C++/WinRT Windows App SDK アプリケーションから前のセクションで作成したコンポーネントを利用する方法を示します。 C++ から C#/WinRT コンポーネントを使うには、現在、単一プロジェクトの Blank App, Packaged (WinUI 3 in Desktop) (空のアプリ、パッケージ (デスクトップの WinUI 3)) テンプレートを使う必要があります。 C# コンポーネントは、クラスの登録なしで C# パッケージ アプリから参照することもできます。
別の Windows アプリケーション パッケージ (WAP) プロジェクトを使うパッケージ アプリからの使用は、現在サポートされていません。 サポートされるプロジェクト構成の最新の更新については、C#/WinRT GitHub リポジトリの「C#/WinRT コンポーネントの作成」をご覧ください。
新しい C++ Windows App SDK アプリケーション プロジェクトをソリューションに追加します。 Visual Studio でソリューションを右クリックし、[追加]>[新しいプロジェクト] を選びます。 Windows App SDKによって提供される Blank App, Packaged (WinUI 3 in Desktop) (空のアプリ、パッケージ (デスクトップの 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
で、次のアクティブ化可能なクラス登録を追加します。 WinUI の型をアクティブにするには、WinUIComponentCs.WinUIComponentCs_XamlTypeInfo.XamlMetaDataProvider クラスの追加のActivatableClass
エントリも必要です。 ファイルを編集するには、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 をご覧ください。 AnyCPU
用にビルドされた C# コンポーネントの C++ からの使用は、現在、x86
アプリケーションからのみサポートされています。x64
およびArm64
アプリでは、次のようなランタイム エラーが発生します: "%1 は有効な Win32 アプリケーションではありません"。詳しくは、Github イシュー #1151 をご覧ください。
関連トピック
Windows developer