XAML マークアップ拡張を使用する

Browse sample. サンプルを参照する

.NET マルチプラットフォーム アプリ UI (.NET MAUI) XAML マークアップ拡張では、要素属性をさまざまなソースから設定できるようにすることで、XAML をより強力かつ柔軟なものにします。

たとえば、通常は次のような BoxViewColor プロパティを設定します。

<BoxView Color="Blue" />

ただし、リソース ディクショナリに格納されている値、または作成したクラスの静的プロパティの値、あるいはページ上の別の要素の型Colorのプロパティから、または個別の色相、彩度、および光度の値から構築された値から Color 属性を設定した方がよいこともあります。 これらすべてのオプションは、XAML マークアップ拡張を使用して実行できます。

マークアップ拡張は、要素の属性を表す別の方法です。 .NET MAUI XAML マークアップ拡張機能は通常、中かっこで囲まれた属性値によって識別できます。

<BoxView Color="{StaticResource themeColor}" />

中かっこ内の属性値は常に XAML マークアップ拡張です。 ただし、中かっこを使用せずに XAML マークアップ拡張機能を参照することもできます。

いくつかの XAML マークアップ拡張は、XAML 2009 仕様の一部です。 これらは、カスタム x 名前空間プレフィックスを持つ XAML ファイルに表示され、一般的にこのプレフィックスで参照されます。

この記事で説明するマークアップ拡張機能のほかにも、次のマークアップ拡張機能が .NET MAUI に含まれており、他の記事で説明されています。

x:Static マークアップ拡張機能

x:Staticマークアップ拡張は、StaticExtension クラスでサポートされています。 クラスには、string型の Member という名前の 1 つのプロパティがあり、パブリック定数、静的プロパティ、静的フィールド、または列挙メンバーの名前に設定します。

x:Static を使用する 1 つの方法は、まず、この AppConstants クラスのような定数または静的変数を持つクラスを定義することです。

static class AppConstants
{
    public static double NormalFontSize = 18;
}

次の XAML は、Label.FontSize プロパティ要素タグ間でStaticExtension クラスをインスタンス化するための最も詳細な方法を示しています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             xmlns:local="clr-namespace:MarkupExtensions"
             x:Class="MarkupExtensions.StaticDemoPage"
             Title="x:Static Demo">
    <StackLayout Margin="10, 0">
        <Label Text="Label No. 1">
            <Label.FontSize>
                <x:StaticExtension Member="local:AppConstants.NormalFontSize" />
            </Label.FontSize>
        </Label>
        ···
    </StackLayout>
</ContentPage>

XAML パーサーでは、StaticExtension クラスを x:Static に短縮することもできます。

<Label Text="Label No. 2">
    <Label.FontSize>
        <x:Static Member="local:AppConstants.NormalFontSize" />
    </Label.FontSize>
</Label>

StaticExtension クラスとメンバーの設定を中かっこで囲むことで、この構文をさらに簡略化できます。 この結果の式は FontSize 属性に直接設定されます。

<Label Text="Label No. 3"
       FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />

この例では、中かっこ内に引用符はありませんStaticExtensionMember プロパティは XML 属性ではなくなります。 その代わり、マークアップ拡張の式の一部になります。

オブジェクト要素として使用する場合に x:StaticExtensionx:Static に短縮できるように、中かっこ内の式で省略することもできます。

<Label Text="Label No. 4"
       FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />

StaticExtension クラスには、プロパティMemberを参照する ContentProperty 属性があり、このプロパティをクラスの既定のコンテンツ プロパティとしてマークします。 中かっこで囲まれた XAML マークアップ式では、式の Member= 部分を削除できます。

<Label Text="Label No. 5"
       FontSize="{x:Static local:AppConstants.NormalFontSize}" />

これは、x:Static マークアップ拡張機能の最も一般的な形式です。

XAML の例のルート タグには、.NET System 名前空間の XML 名前空間宣言も含まれています。 これにより、 Label フォント サイズを静的フィールド Math.PIに設定できます。 その結果、テキストが小さくなるので、Scale プロパティは Math.E に設定されます。

<Label Text="&#x03C0; &#x00D7; E sized text"
       FontSize="{x:Static sys:Math.PI}"
       Scale="{x:Static sys:Math.E}"
       HorizontalOptions="Center" />

次のスクリーンショットは XAML 出力を示しています。

x:Static demo.

x:Reference マークアップ拡張機能

x:Referenceマークアップ拡張は、ReferenceExtension クラスでサポートされています。 クラスには、string 型の Name という名前の 1 つのプロパティがあり、x:Name という名前が付けられたページ上の要素の名前に設定します。 この Name プロパティは ReferenceExtension の content プロパティなので、x:Reference が中かっこで囲まれている場合、Name= は必要ありません。 x:Referenceマークアップ拡張機能は、データ バインディングでのみ使用されます。 データ バインディングの詳細については、「 データ バインディング」を参照してください。

次の XAML の例は、データ バインディングでのx:Reference の 2 つの使用方法を示しています。1 つ目は Bindingオブジェクトの Source プロパティの設定で使用され、2 つ目は 2 つのデータ バインディングの BindingContext プロパティの設定で使用されます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.ReferenceDemoPage"
             x:Name="page"
             Title="x:Reference Demo">    
    <StackLayout Margin="10, 0">        
        <Label Text="{Binding Source={x:Reference page},
                              StringFormat='The type of this page is {0}'}"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalTextAlignment="Center" />
        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
        <Label BindingContext="{x:Reference slider}"
               Text="{Binding Value, StringFormat='{0:F0}&#x00B0; rotation'}"
               Rotation="{Binding Value}"
               FontSize="24"
               HorizontalOptions="Center"
               VerticalOptions="Center" />        
    </StackLayout>
</ContentPage>

この例では、両方 x:Reference の式で ReferenceExtension クラス名の省略形が使用され、式の Name= 部分が削除されます。 最初の例では、x:Reference マークアップ拡張機能は Binding マークアップ拡張機能に埋め込まれており、Source および StringFormat プロパティはコンマで区切られています。

次のスクリーンショットは XAML 出力を示しています。

x:Reference demo.

x:Type マークアップ拡張機能

x:Typeマークアップ拡張機能は、C# typeof キーワードと同等の XAML です。 これは、TypeExtension クラスでサポートされており、クラスまたは構造体名に設定する必要がある型 stringTypeName という名前のプロパティを定義します。 x:Type マークアップ拡張機能は、そのクラスまたは構造体の Type オブジェクトを返します。 TypeNameTypeExtension の content プロパティなので、x:Type が中かっこで囲まれている場合、TypeName= は必要ありません。

x:Typeマークアップ拡張機能は一般的に x:Array マークアップ拡張機能と共に使用されます。 詳細については、「 x:Array マークアップ拡張機能」を参照してください。

次の XAML の例では、x:Type マークアップ拡張機能を 使用して .NET MAUI オブジェクトをインスタンス化し、StackLayout に追加する方法を示しています。 XAML は、Command プロパティが Binding に設定されている 3 つの Button と、3 つの .NET MAUI ビューの型に設定されたCommandParameterプロパティで構成されています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.TypeDemoPage"
             Title="x:Type Demo">    
    <StackLayout x:Name="stackLayout"
                 Padding="10, 0">        
        <Button Text="Create a Slider"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Slider}" />
        <Button Text="Create a Stepper"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Stepper}" />
        <Button Text="Create a Switch"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Switch}" />
    </StackLayout>
</ContentPage>

コードビハインド ファイルは、CreateCommand プロパティを定義して初期化します。

public partial class TypeDemoPage : ContentPage
{
    public ICommand CreateCommand { get; private set; }

    public TypeDemoPage()
    {
        InitializeComponent();

        CreateCommand = new Command<Type>((Type viewType) =>
        {
            View view = (View)Activator.CreateInstance(viewType);
            view.VerticalOptions = LayoutOptions.Center;
            stackLayout.Add(view);
        });

        BindingContext = this;
    }
}

Button を押すと、CommandParameter 引数の 新しいインスタンスが作成され、StackLayout に追加されます。 その後、3 つの Button オブジェクトは、動的に作成されたビューとページを共有します。

x:Type demo.

x:Array マークアップ拡張機能

x:Arrayマークアップ拡張機能を使用すると、マークアップで配列を定義できます。 これは、次の 2 つのプロパティを定義する ArrayExtension クラスでサポートされています。

  • TypeType は、配列内の要素の型を示します。 このプロパティは、x:Type マークアップ拡張機能に設定する必要があります。
  • IListItems は項目自体のコレクションです。 これは、ArrayExtension の content プロパティです。

x:Array マークアップ拡張機能自体が中かっこで囲まれることはありません。 その代わり、 x:Array 開始タグと終了タグによって項目のリストが区切られます。

次の XAML の例は、x:Array を使用して、ItemsSource プロパティを配列に設定することでListView に追加する方法を示しています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.ArrayDemoPage"
             Title="x:Array Demo Page">
    <ListView Margin="10">
        <ListView.ItemsSource>
            <x:Array Type="{x:Type Color}">
                <Color>Aqua</Color>
                <Color>Black</Color>
                <Color>Blue</Color>
                <Color>Fuchsia</Color>
                <Color>Gray</Color>
                <Color>Green</Color>
                <Color>Lime</Color>
                <Color>Maroon</Color>
                <Color>Navy</Color>
                <Color>Olive</Color>
                <Color>Pink</Color>
                <Color>Purple</Color>
                <Color>Red</Color>
                <Color>Silver</Color>
                <Color>Teal</Color>
                <Color>White</Color>
                <Color>Yellow</Color>
            </x:Array>
        </ListView.ItemsSource>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <BoxView Color="{Binding}"
                             Margin="3" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>     

この例では、ViewCell がカラー エントリごとに単純な BoxView を作成します。

x:Array demo.

文字列や数値などの一般的な型の配列を定義する場合は、「因数を渡す」に記載されている XAML 言語プリミティブ タグを使用します。

x:Null マークアップ拡張機能

x:Nullマークアップ拡張は、NullExtension クラスでサポートされています。 プロパティは含まれておらず、単に C# null キーワードと同等の XAML です。

次の XAML の例は、x:Null マークアップ拡張機能を使用する方法を示しています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.NullDemoPage"
             Title="x:Null Demo">
    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="48" />
            <Setter Property="FontFamily" Value="OpenSansRegular" />
        </Style>
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">
        <Label Text="Text 1" />
        <Label Text="Text 2" />
        <Label Text="Text 3"
               FontFamily="{x:Null}" />
        <Label Text="Text 4" />
        <Label Text="Text 5" />
    </StackLayout>
</ContentPage>      

この例では、暗黙的な StyleLabel で定義されており、この中には FontFamily プロパティを特定のフォントに設定する Setter が含まれています。 ただし、3 つ目の Label は、FontFamilyx:Null に設定することにより、暗黙的なスタイルで定義されているフォントの使用を回避します。

x:Null demo.

DataTemplate マークアップ拡張機能

DataTemplate マークアップ拡張機能を使用すると、型を DataTemplate に変換できます。 これは、string 型の TypeName プロパティを定義する DataTemplateExtension クラスでサポートされ、DataTemplateに変換される型の名前に設定されます。 TypeName プロパティは、DataTemplateExtension の content プロパティです。 そのため、中かっこで囲まれた XAML マークアップ式では、式の TypeName= 部分を削除できます。

XAML パーサーでは、DataTemplateExtension クラスを DataTemplate に短縮できます。

このマークアップ拡張機能の一般的な使用方法は、次の例に示すように、シェル アプリケーションにあります。

<ShellContent Title="Monkeys"
              Icon="monkey.png"
              ContentTemplate="{DataTemplate views:MonkeysPage}" />

この例では、MonkeysPageContentPage から DataTemplate に変換しており、これは ShellContent.ContentTemplate プロパティの値として設定されています。 これにより、アプリケーションの スタートアップ時ではなく、ページへのナビゲーション時にのみ MonkeysPage が作成されます。

シェル アプリの詳細については、「 シェル」を参照してください。