前回までは、WPF の主要なクラスや継承階層を見てきました。
今回からは、WPF の画面定義で使う XAML の構文 を整理します。XAML は XML をもとにした記法ですが、単なる XML 文書ではありません。WPF のオブジェクトを生成し、プロパティに値を設定し、必要に応じてコード側のクラスと結び付けるための記法です。
最初に押さえたいのは、XAML ファイルの先頭に出てくる名前空間です。
<Window x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Sample"
Width="400"
Height="250">
<Grid>
<Button Content="OK" />
</Grid>
</Window>
この例には、WPF の XAML を読むうえで重要な要素がいくつも含まれています。
XML 名前空間とは
XML では、要素名や属性名がどの語彙に属するかを名前空間で区別します。
WPF の XAML でも同じです。Window、Grid、Button という名前が、どのライブラリの型を指すのかを明確にするために名前空間を使います。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
これは、接頭辞を付けない要素名を WPF の画面部品として解釈するための指定です。
この指定があるため、次のように書けます。
<Grid>
<Button Content="OK" />
</Grid>
Grid や Button に接頭辞が付いていないため、既定の名前空間に属する要素として扱われます。WPF アプリケーションでは、通常この既定の名前空間に WPF の表示部品を割り当てます。
既定の名前空間
既定の名前空間は、接頭辞のない要素に適用されます。
<Window>
<StackPanel>
<TextBlock Text="名前" />
<TextBox />
</StackPanel>
</Window>
この例では、Window、StackPanel、TextBlock、TextBox がすべて既定の名前空間に属します。
XAML を読み込むとき、これらの要素は WPF の型に対応付けられます。
| XAML の要素 | 対応する WPF の型 |
|---|---|
Window |
System.Windows.Window |
Grid |
System.Windows.Controls.Grid |
Button |
System.Windows.Controls.Button |
TextBlock |
System.Windows.Controls.TextBlock |
TextBox |
System.Windows.Controls.TextBox |
つまり、XAML の要素名は、多くの場合 .NET の型名に対応しています。
x 名前空間
もうひとつ重要なのが、x という接頭辞を持つ名前空間です。
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
これは WPF 固有の部品ではなく、XAML 言語そのものが持つ機能を使うための名前空間です。
代表的なものには、次のような指定があります。
| 指定 | 役割 |
|---|---|
x:Class |
XAML とコード側のクラスを結び付ける |
x:Name |
要素に名前を付け、コード側から参照できるようにする |
x:Key |
リソースにキーを付ける |
x:Static |
静的メンバーを参照する |
x:Null |
null 値を表す |
x:Type |
型そのものを表す |
このような x: 付きの指定は、WPF のコントロールのプロパティというより、XAML を解釈するための特別な指定です。
x:Class
x:Class は、XAML ファイルがどのクラスの一部になるかを指定します。
<Window x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Window>
この例では、XAML が SampleApp.MainWindow クラスと結び付きます。
通常、対応するコード側には次のようなクラスがあります。
namespace SampleApp;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
partial になっている点が重要です。XAML から生成されるコードと、自分で書くコードが、同じクラスの別々の部分として合成されます。
XAML に書いた画面構造は、ビルド時に読み込まれ、InitializeComponent によって初期化されます。
x:Name
x:Name は、XAML 内の要素に名前を付けるための指定です。
<Button x:Name="SaveButton"
Content="保存" />
名前を付けると、コード側からその要素を参照できます。
SaveButton.Content = "保存しました";
ただし、すべての要素に名前を付ける必要はありません。コード側から直接操作する必要がある要素だけに名前を付けるのが基本です。
たとえば、単に画面に表示するだけの TextBlock であれば、名前を付けなくてもかまいません。
<TextBlock Text="処理が完了しました。" />
一方、実行中に表示内容を変更したい場合は、名前を付ける意味があります。
<TextBlock x:Name="StatusText"
Text="待機中" />
x:Key
x:Key は、リソースを識別するためのキーを指定します。
<Window.Resources>
<SolidColorBrush x:Key="AccentBrush"
Color="SteelBlue" />
</Window.Resources>
定義したリソースは、別の場所から参照できます。
<Button Content="保存"
Background="{StaticResource AccentBrush}" />
x:Name は要素に名前を付けてコードから参照するために使います。x:Key はリソース辞書の中で値を探すためのキーとして使います。
似て見えますが、目的は異なります。
clr-namespace による名前空間
自分で作ったクラスを XAML から使いたい場合は、.NET の名前空間を XAML の名前空間として割り当てます。
<Window x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApp">
</Window>
この例では、local という接頭辞で SampleApp 名前空間内の型を参照できます。
たとえば、SampleApp 名前空間に UserCard というユーザーコントロールがあれば、次のように書けます。
<local:UserCard />
既定の名前空間は WPF の標準部品に使い、local のような接頭辞付き名前空間は自分の型や別ライブラリの型を使うために利用します。
まとめ
XAML の先頭に書かれる名前空間は、長く見えるため最初は読みにくいかもしれません。しかし、役割は整理できます。
| 書き方 | 役割 |
|---|---|
xmlns="..." |
接頭辞のない要素をどの名前空間の型として扱うかを決める |
xmlns:x="..." |
XAML 言語の特別な指定を使えるようにする |
xmlns:local="clr-namespace:..." |
自分の .NET 名前空間に接頭辞を割り当てる |
x:Class |
XAML とコード側のクラスを結び付ける |
x:Name |
要素に名前を付けてコード側から参照できるようにする |
x:Key |
リソース辞書内の値にキーを付ける |
XAML の要素は、多くの場合 .NET の型に対応します。属性は、その型のプロパティに値を設定します。そして x: 付きの指定は、XAML の読み込みやコード生成に関わる特別な意味を持ちます。
次回は、x:Class や x:Name と関係の深い、クラスとメンバー変数の見え方について整理します。