Webのフロントエンドのコンポーネントに相当するWinUI3のパーツはCustom ControlかUser Controlである。 Custom Controlはより低レベルの概念であり、独自の動作と描画ロジックを持てる。 対してUser Controlは既存のコントロール(UIパーツ)の組み合わせであり、フロントエンド用語のコンポーネントにより近いと思われる。
まずはUser Controlとして実装することを考え、User Controlで実現不可能な場合だけCustom Controlとして実装することを検討すると良い。 この記事では以降User Controlにだけ言及する。 また、実用性よりも分かりやすさを優先し、この記事では機能を抑えたUser Controlを作成する。
最低限のUser Controlを作成する
ここではStackPanel内にTextBoxとTextBlockを並べた塊をUser Controlとして作成する。 TextBoxに入力されている文字列が変化したことをイベントハンドラでキャッチし、TextBlockに反映する。
User Controlの実装
User Controlは名前通りWindows.UI.Xaml.Controls.UserControl
というクラスを継承して実装する。
公式のドキュメントはこれ
UserControl クラス (Windows.UI.Xaml.Controls) - Windows UWP applications | Microsoft Learn
Visual Stdioの機能で作成する場合は「新しい項目の追加」ダイアログから「ユーザーコントロール(WinUI 3)」を選択する。 ここではComponents/ ディレクトリ配下に作成し、名前はFormTextInputとする。
生成された.xamlファイルと.xaml.csファイルを少し修正し、以下のようにする。
Components/FormTextInput.xaml
<?xml version="1.0" encoding="utf-8"?> <UserControl x:Class="foo.Components.FormTextInput" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:foo.Components" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Orientation="Vertical"> <TextBox x:Name="InputTextBox" TextChanged="InputTextChanged" /> <TextBlock x:Name="Message"/> </StackPanel> </UserControl>
Components/FormTextInput.xaml.cs
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; namespace foo.Components { public sealed partial class FormTextInput : UserControl { public FormTextInput() { this.InitializeComponent(); } // TextBoxの文字が変更された際に発火するイベントハンドラ private void InputTextChanged(object sender, TextChangedEventArgs e) { Message.Text = InputTextBox.Text; } } }
x:Name
を設定して、.xaml.cs側でインスタンスに名前でアクセスできるようにしている。
実用性はともかく、これでFormTextInput
というUser Controlが作成できた。
作成したUser Controlの使い方
作成したUser Controlを、利用したいXAML中で名前空間としてインポートする。
例えば、以下に示すBarPageではxmlns:u="using:foo.Components"
という記述より、u:
で参照できるようになる。
例えば次のように記述すると、localという名前空間が定義される。
xmlns:local="using:foo.Components"
すると、そのXMLでは接頭辞を用いてlocal:Baz
のように参照できる。
当然、次のように記述すれば、a:Baz
のように参照できる。
xmlns:a="using:foo.Components"
BarPage.xaml
<?xml version="1.0" encoding="utf-8"?> <Page x:Class="foo.BarPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:u="using:foo.Components" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <!-- 途中略 --> <u:FormTextInput /> <!-- 以下略 -->
User Controlをもっと実用的に作る
この記事では単純なUser Controlを作成したが、実際のアプリケーションにおいてパーツとして再利用するためにはもう少し作りこみが必要だろう。 記事のスコープを狭めるため、発展的な内容については別の記事にメモする。