次の方法で共有


基本的な XAML 構文

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

XAML は、主にオブジェクトのインスタンス化と初期化を目的として設計されています。 ただし、多くの場合、プロパティは XML 文字列として簡単に表現できない複合オブジェクトに設定する必要があり、1 つのクラスで定義されたプロパティを子クラスに設定する必要があります。 この 2 つでは、プロパティ要素添付プロパティの基本的な XAML 構文機能が必要です。

プロパティ要素

.NET マルチプラットフォーム アプリ UI (.NET MAUI) XAML では、クラスのプロパティは通常、XML 属性として設定されます。

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="18"
       TextColor="Aqua" />

ただし、XAML でプロパティを設定する別の方法もあります。

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="18">
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

TextColor プロパティを指定する次の 2 つの例は機能的に同等で、いくつかの基本的な用語の導入が可能です。

  • Labelオブジェクト要素です。 XML 要素として表される .NET MAUI オブジェクトです。
  • TextVerticalOptionsFontAttributesおよび FontSizeは、プロパティ属性です。 これらは、XML 属性として表される .NET MAUI プロパティです。
  • 2 番目の例では、TextColorプロパティ要素になっています。 XML 要素として表される .NET MAUI プロパティです。

プロパティ要素では、プロパティの値は常に、プロパティ要素の開始タグと終了タグの間のコンテンツとして定義されます。

プロパティ要素の構文は、オブジェクトの複数のプロパティでも使用できます。

<Label Text="Hello, XAML!"
       VerticalOptions="Center">
    <Label.FontAttributes>
        Bold
    </Label.FontAttributes>
    <Label.FontSize>
        Large
    </Label.FontSize>
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

プロパティ要素の構文は不要に思えるかもしれませんが、プロパティの値が複雑すぎて単純な文字列として表現できない場合には不可欠です。 プロパティ要素タグ内では、別のオブジェクトをインスタンス化し、そのプロパティを設定できます。 たとえば、Grid レイアウトには RowDefinitionsColumnDefinitions という名前のプロパティがあり、それぞれRowDefinitionCollection および ColumnDefinitionCollection 型になっています。 これらの型は RowDefinitionColumnDefinition オブジェクトのコレクションであり、通常はプロパティ要素の構文を使用して設定します。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        ...
    </Grid>
</ContentPage>

添付プロパティ

前の例では、行と列を定義するために、GridRowDefinitions および ColumnDefinitions のプロパティ要素が必要であることを確認しました。 これは、Grid のそれぞれの子が存在する行と列を示す手法が必要であることを示唆しています。

Grid のそれぞれの子のタグ内で、既定値が 0 である Grid.RowGrid.Column の属性を使用して子の行と列を指定します。 また、子が複数の行または列にまたがり、既定値が 1 のGrid.ColumnSpan および Grid.RowSpan 属性を持つかどうか指定することもできます。

次の例は、Grid 内に子を配置する方法を示しています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>

        <Label Text="Autosized cell"
               TextColor="White"
               BackgroundColor="Blue" />
        <BoxView Color="Silver"
                 Grid.Column="1" />
        <BoxView Color="Teal"
                 Grid.Row="1" />
        <Label Text="Leftover space"
               Grid.Row="1" Grid.Column="1"
               TextColor="Purple"
               BackgroundColor="Aqua"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
        <Label Text="Span two rows (or more if you want)"
               Grid.Column="2" Grid.RowSpan="2"
               TextColor="Yellow"
               BackgroundColor="Blue"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
        <Label Text="Span two columns"
               Grid.Row="2" Grid.ColumnSpan="2"
               TextColor="Blue"
               BackgroundColor="Yellow"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
        <Label Text="Fixed 100x100"
               Grid.Row="2" Grid.Column="2"
               TextColor="Aqua"
               BackgroundColor="Red"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

    </Grid>
</ContentPage>

この XAML の結果、レイアウトは次のようになります。

.NET MAUI Grid layout.

Grid.RowGrid.ColumnGrid.RowSpanGrid.ColumnSpan 属性は Grid クラスのプロパティのように見えますが、このクラスは RowColumnRowSpan、または ColumnSpan という名前のものは定義しません。 その代わり、Grid クラスは RowPropertyColumnPropertyRowSpanPropertyColumnSpanProperty という名前のバインディング可能な 4 つのプロパティを定義します。これは、添付プロパティと呼ばれる特別なタイプのバインディング可能なプロパティです。 これらは Grid クラスによって定義されますが、 Grid の子で設定されます。

これらの添付プロパティをコードで使用する場合、Grid クラスは GetRowSetRowGetColumnSetColumnGetRowSpanSetRowSpanGetColumnSpanSetColumnSpanという名前の静的メソッドを提供します。

添付プロパティは、ピリオドで区切ったクラスとプロパティ両方の名前を含む属性として XAML で認識できます。 これらが添付プロパティと呼ばれるのは、1 つのクラス (この場合は Grid) で定義され、別のオブジェクト (この場合は Grid の子) に添付されるためです。 レイアウト中に Grid は、これらの添付プロパティの値を調べて、それぞれの子を配置する場所を把握することができます。

コンテンツ プロパティ

前の例では、Grid オブジェクトは ContentPageContent プロパティに設定されていました。 ただし、Content プロパティは XAML で参照されませんでしたが、以下が可能です。

<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">
    <ContentPage.Content>
        <Grid>
            ...
        </Grid>
    </ContentPage.Content>
</ContentPage>

Content プロパティは XAML では必要ありません、.NET MAUI XAML で使用するよう定義された要素がクラスの ContentProperty 属性としてプロパティを 1 つ指定できるためです。

[ContentProperty("Content")]
public class ContentPage : TemplatedPage
{
    ...
}

クラスの ContentProperty としてプロパティが指定されているということは、プロパティ要素タグが不要であることを意味します。 したがって、上の例では、開始タグと終了 ContentPage タグの間に表示される XAML コンテンツが Content プロパティに割り当てられるよう指定しています。

多くのクラスには ContentProperty 属性定義もあります。 たとえば、Label のコンテンツ プロパティは Text です。

プラットフォームによる違い

.NET MAUI アプリでは、プラットフォームごとに UI の外観をカスタマイズできます。 これは、XAML でOnPlatform および Onクラスを使用して実現できます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0,20,0,0" />
            <On Platform="Android" Value="10,20,20,10" />
        </OnPlatform>
    </ContentPage.Padding>
    ...
</ContentPage>

OnPlatform はジェネリック クラスなので、ジェネリック型の引数を指定する必要があります。この場合は、Padding プロパティの型である Thickness です。 これは x:TypeArguments XAML 属性を使用して行われます。 OnPlatform クラスは Defaultプロパティを定義し、このプロパティはすべてのプラットフォームに適用される値に設定できます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness" Default="20">
            <On Platform="iOS" Value="0,20,0,0" />
            <On Platform="Android" Value="10,20,20,10" />
        </OnPlatform>
    </ContentPage.Padding>
    ...
</ContentPage>

この例では、Padding プロパティは iOS と Android で異なる値に設定され、他のプラットフォームでは既定値に設定されています。

OnPlatform クラスは、Onオブジェクトの IList である Platforms プロパティも定義します。 各 On オブジェクトは Platform および Value プロパティを設定して、特定のプラットフォームの Thickness 値を定義できます。 さらに、 OnPlatform プロパティは IList<string> 型なので、値が同じ場合に複数のプラットフォームを含めることができます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness" Default="20">
            <On Platform="iOS, Android" Value="10,20,20,10" />
        </OnPlatform>
    </ContentPage.Padding>
    ...
</ContentPage>

これは、XAML でプラットフォーム依存 Padding プロパティを設定する標準的な方法です。

On オブジェクトの Value プロパティを 1 つの文字列で表せない場合は、そのプロパティ要素を定義できます。

詳細については、「プラットフォームに基づいて UI の外観をカスタマイズする」を参照してください。

次のステップ

.NET MAUI XAML マークアップ拡張を使用すると、他のソースから間接的に参照されるオブジェクトまたは値にプロパティを設定できます。 XAML マークアップ拡張は、オブジェクトを共有したり、アプリ全体で使用される定数を参照したりする際、特に重要です。