XAML の使用を開始する
.NET マルチプラットフォーム アプリ UI (.NET MAUI) アプリでは、XAML は主にページのビジュアル コンテンツを定義するために使用され、C# コードビハインド ファイルと連携します。 コードビハインド ファイルは、マークアップのコード サポートを提供します。 これら 2 つのファイルは、子ビューとプロパティの初期化を含む新しいクラス定義に貢献します。 XAML ファイル内では、クラスとプロパティは XML 要素と属性で参照され、マークアップとコード間のリンクが確立されます。
XAML ファイルの構造
新しい .NET MAUI アプリには、3 つの XAML ファイルとそれに関連するコードビハインド ファイルが含まれています。
最初のファイル ペアリングは、App.xaml (XAML ファイル) と App.xaml.cs (XAML ファイルに関連のある C# コードビハインド ファイル)です。 App.xaml と App.xaml.cs は両方とも、Application
から派生した App
という名前のクラスに貢献します。 2 番目のファイル ペアリングは、AppShell.xaml と AppShell.xaml.cs です。これは、Shell から派生した AppShell
という名前のクラスに貢献します。 XAML ファイルのある他のほとんどのクラスは、ContentPage から派生するクラスに貢献し、ページの UI を定義します。 これは、MainPage.xaml および MainPage.xaml.cs ファイルに当てはまります。
MainPage.xaml ファイルの構造は次のとおりです。
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
...
</ContentPage>
2 つの XML 名前空間 (xmlns
) 宣言は、microsoft.com の URI を参照します。 ただし、これらの URI にコンテンツはなく、基本的にバージョン識別子として機能します。
最初の XML 名前空間宣言は、プレフィックスのない XAML ファイル内で定義されたタグが、.NET MAUI のクラスを参照することを意味します (たとえば、ContentPage)。 2 番目の名前空間宣言では、x
のプレフィックスを定義します。 これは、XAML 自体に組み込まれ、XAML の他の実装でサポートされている複数の要素と属性で使用されます。 ただし、これらの要素と属性は、URI に埋め込まれた年によって若干異なります。 .NET MAUI では、2009 XAML 仕様がサポートされています。
最初のタグの末尾で、x
プレフィックスが名前付きの Class
属性に使用されます。 この x
プレフィックスの使用は XAML 名前空間で実質的に汎用なので、Class
のような XAML 属性はほとんどの場合、x:Class
として参照されます。 x:Class
属性は、完全修飾 .NET クラス名 (MyMauiApp
名前空間の MainPage
クラス) を指定します。 つまり、この XAML ファイルは、ContentPage (x:Class
属性が現れるタグ) から派生する MyMauiApp
名前空間で MainPage
という名前の新しいクラスを定義します。
x:Class
属性は、派生した C# クラスを定義するために XAML ファイルのルート要素にのみ表示できます。 これは、XAML ファイルで定義されている唯一の新しいクラスです。 XAML ファイルに表示される他のものはすべて、既存のクラスからインスタンス化され、初期化されます。
MainPage.xaml.cs ファイルは次のようになります。
namespace MyMauiApp;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
MainPage
クラスはContentPage から派生し、部分的なクラスの定義です。
Visual Studio がプロジェクトをビルドすると、ソース ジェネレーターによって、MainPage
コンストラクターから呼び出される InitializeComponent
メソッドの定義を含む新しい C# ソースが生成され、コンパイル オブジェクトに追加されます。
ランタイム時に、MauiProgram
クラスのコードによってアプリがブートストラップされ、App
クラス コンストラクターが実行され、AppShell
がインスタンス化されます。 AppShell
クラスは、表示 されるアプリの最初のページをインスタンス化します (MainPage
)。 MainPage
コンストラクターは InitializeComponent
を呼び出します。これにより、XAML ファイルで定義されているすべてのオブジェクトを初期化し、それらをすべて親子関係で接続し、コードで定義されたイベント ハンドラーを XAML ファイルで設定されたイベントに添付し、その結果生じるオブジェクト ツリーをページのコンテンツとして設定します。
注
AppShell
クラスでは、.NET MAUI シェルを使用して、表示するアプリの最初のページを設定します。 ただし、シェルは、この XAML 概要の範疇ではありません。 詳細については、「.NET MAUI シェル」を参照してください。
ページ コンテンツを設定する
ContentPage には 1 つの子が含まれている必要があります。これは、ビューまたは子ビューを含むレイアウトにすることができます。 ContentPage の子は、ContentPage.Content
プロパティの値として自動的に設定されます。
次の例は、Label が含まれている ContentPage です:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage"
Title="Hello XAML Page">
<Label Text="Hello, XAML!"
VerticalOptions="Center"
HorizontalTextAlignment="Center"
Rotation="-15"
FontSize="18"
FontAttributes="Bold"
TextColor="Blue" />
</ContentPage>
上記の例では、クラス、プロパティ、および XML の関係が明らかです。 .NET MAUI クラス (Label または ContentPage など) は、XML 要素として XAML ファイルに表示されます。 通常、そのクラスのプロパティ (ContentPage の Title
と Label の 7 個のプロパティを含む) は XML 属性として表示されます。
これらのプロパティの値を設定するための多くのショートカットが存在します。 一部のプロパティは基本的なデータ型です。 たとえば、Title
と Text
プロパティは string
型、Rotation
は double
型です。 HorizontalTextAlignment
プロパティは TextAlignment 型 (列挙型) です。 任意の列挙型のプロパティの場合、指定する必要があるのはメンバー名のみです。
ただし、より複雑な型のプロパティの場合は、XAML の解析にコンバーターが使用されます。 これらは TypeConverter
から派生した .NET MAUI のクラスです。 上記の例では、文字列値を正しい型に変換するために、複数の .NET MAUI コンバーターが自動的に適用されます:
VerticalOptions
プロパティのLayoutOptionsConverter
。 このコンバーターは、LayoutOptions
構造の公開用静的フィールドの名前をLayoutOptions
型の値に変換します。TextColor
プロパティのColorTypeConverter
。 このコンバーターは、アルファ チャネルの有無にかかわらず、Colors クラスまたは 16 進数の RGB 値の公開用静的フィールドの名前を変換します。
ページの移動
.NET MAUI アプリを実行すると、通常は MainPage
が表示されます。 別のページを表示するには、AppShell.xaml ファイルで新しいスタートアップ ページとして設定するか、MainPage
から新しいページに移動できます。
ナビゲーションを実装するには、MainPage.xaml.cs コンストラクターでシンプルな Button を作成し、イベント ハンドラーを使って HelloXamlPage
に移動できます:
public MainPage()
{
InitializeComponent();
Button button = new Button
{
Text = "Navigate!",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) =>
{
await Navigation.PushAsync(new HelloXamlPage());
};
Content = button;
}
このアプリの新しいバージョンをコンパイルして展開すると、画面にボタンが表示されます。 これを押すと、HelloXamlPage
に移動します:
各プラットフォームに表示されるナビゲーションバーを使用して、MainPage
に戻ることができます。
注
このナビゲーション モデルの代わりに、.NET MAUI シェルを使用できます。 詳細については、「.NET MAUI シェルの概要」を参照してください。
XAML とコードの相互作用
ほとんどの ContentPage 派生物の子は、StackLayout や Grid などのレイアウトで、レイアウトには複数の子を含めることができます。 XAML では、親子関係が通常の XML 階層で確立されます:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="Center" />
<Label Text="A simple Label"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
この XAML ファイルは構文的に完全であり、次の UI が生成されます:
ただし、Slider と Button を操作することはできますが、UI は更新されません。 Slider によって Label には現在の値が表示され、Button が動作を行うはずです。
Label を使用した Slider 値の表示は、データ バインディングを使って完全に XAML で実行できます。 ただし、最初にコード ソリューションを確認すると便利です。 それでも、Button クリックを処理するには間違いなくコードが必要です。 つまり、XamlPlusCodePage
のコードビハインド ファイルには、Slider の ValueChanged
イベントと ButtonのClicked
イベントのハンドラーを含める必要があります:
namespace XamlSamples
{
public partial class XamlPlusCodePage
{
public XamlPlusCodePage()
{
InitializeComponent();
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}
}
}
XAML ファイルに戻り、Slider および Button タグには、これらのハンドラーを参照する ValueChanged
と Clicked
イベントの属性を含めなくてはなりません。
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="Center"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="valueLabel"
Text="A simple Label"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="Center"
Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
イベントにハンドラーを割り当てる構文は、プロパティに値を割り当てる場合と同じ構文であることに注意してください。 さらに、Slider の ValueChanged
イベント ハンドラーが Label を使用して現在の値を表示するには、ハンドラーがそのオブジェクトをコードから参照する必要があります。 そのため、Label には、x:Name
属性で指定される名前が必要です。 x:Name
属性の x
のプレフィックスは、この属性が XAML に組み込まれていることを示します。 x:Name
属性に割り当てる名前には、C# 変数名と同じ規則があります。 たとえば、文字またはアンダースコアで始まり、スペースを埋め込まないなどです。
ValueChanged
イベント ハンドラーは、イベント引数から使用できる新しい Slider 値を表示するように Label をできるようになりました。
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
また、ハンドラーは、sender
引数からこのイベントを生成する Slider オブジェクトを取得し、そこから Value
プロパティを取得できます。
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}
その結果、Slider の操作を行うと、その値が Label に表示されます:
上記の例では、ボタンの Text
でアラートを表示してButton が Clicked
イベントへの応答をシミュレートしています。 そのため、イベント ハンドラーは sender
引数を Button にキャストし、そのプロパティにアクセスできます。
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}
OnButtonClicked
メソッドは async
として定義されます。DisplayAlert メソッドは非同期で、メソッドの完了時に返される await
演算子で始まる必要があるためです。 このメソッドは sender
引数からイベントを発生させる Button を取得するため、複数のボタンで同じハンドラーを使用できます。
次のステップ
XAML は、主にオブジェクトのインスタンス化と初期化を目的として設計されています。 ただし、多くの場合、プロパティは XML 文字列として簡単に表すことができない複合オブジェクトに設定する必要があり、1 つのクラスで定義されたプロパティを子クラスに設定する必要がある場合があります。 この 2 つでは、プロパティ要素と添付プロパティの基本的な XAML 構文機能が必要です。
.NET MAUI