次の方法で共有


XAML マークアップ拡張

サンプルを参照します。 サンプルを参照する

.NET マルチプラットフォーム アプリ UI (.NET MAUI) XAML マークアップ拡張を使用すると、他のソースから間接的に参照されるオブジェクトまたは値にプロパティを設定できます。 XAML マークアップ拡張は、オブジェクトを共有したり、アプリ全体で使用される定数を参照したりする際、特に重要ですが、最も役に立つのはデータ バインディングです。

通常、XAML を使用して、オブジェクトのプロパティを明示的な値 (文字列、数値、列挙型メンバー、バックグラウンドで値に変換される文字列など) に設定します。 ただし、プロパティが別の場所で定義されている値を参照する必要がある場合や、ランタイムにコードによる処理が少し必要になる場合があります。 このような目的で、XAML マークアップ拡張機能を使用できます。

XAML マークアップ拡張は、IMarkupExtension を実装するクラスのコードによってサポートされているため、名前が付けられます。 独自のカスタム マークアップ拡張を記述することもできます。

多くの場合、XAML マークアップ拡張は、中かっこ { と } で区切られた属性値として表示されるため、XAML ファイルですぐに認識できますが、マークアップ拡張も従来の要素としてマークアップに表示されることがあります。

重要

マークアップ拡張はプロパティを持つことができますが、XML 属性のように設定されません。 マークアップ拡張では、プロパティ設定はコンマで区切られ、中かっこ内に引用符は表示されません。

共有リソース

一部の XAML ページには、プロパティが同じ値に設定された複数のビューが含まれています。 たとえば、これらの Button オブジェクトのプロパティ設定の多くは同じです。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">
    <StackLayout>
        <Button Text="Do this!"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                BorderWidth="3"
                Rotation="-15"
                TextColor="Red"
                FontSize="24" />
        <Button Text="Do that!"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                BorderWidth="3"
                Rotation="-15"
                TextColor="Red"
                FontSize="24" />
        <Button Text="Do the other thing!"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                BorderWidth="3"
                Rotation="-15"
                TextColor="Red"
                FontSize="24" />
    </StackLayout>
</ContentPage>

これらのプロパティのいずれかを変更する必要がある場合は、変更を 3 回ではなく 1 回だけ行った方がいいでしょう。 これがコードの場合は、定数と静的な読み取り専用オブジェクトを使用すると、このような値の一貫性を保ち、変更しやすくなる可能性があります。

XAML で一般的な解決策の 1 つは、このような値またはオブジェクトをリソース ディクショナリに格納することです。 VisualElement クラスは、ResourceDictionary 型の Resources という名前のプロパティを定義します。これは、string 型のキーとobject 型の値があるディクショナリです。 このディクショナリにオブジェクトを配置し、マークアップから参照できます。これはすべて XAML で実行できます。

ページでリソース ディクショナリを使用するには、ページの上部で Resources プロパティ要素タグのペアを含め、これらのタグ内にリソースを追加します。 さまざまな型のオブジェクトと値をリソース ディクショナリに追加できます。 これらの型はインスタンス化できなくてはなりません。 たとえば、抽象クラスにすることはできません。 この型には、パラメーターのない公開用コンストラクターが必要です。 各項目には、x:Key 属性で指定されたディクショナリ キーが必要です。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">
    <ContentPage.Resources>
        <LayoutOptions x:Key="horzOptions"
                       Alignment="Center" />
        <LayoutOptions x:Key="vertOptions"
                       Alignment="Center" />
    </ContentPage.Resources>
    ...
</ContentPage>

この例では、2 つのリソースは構造型 LayoutOptions の値であり、それぞれに一意のキーと 1 つまたは 2 つのプロパティが設定されています。 コードとマークアップでは、LayoutOptions の静的フィールドを使用する方がはるかに一般的ですが、ここではプロパティを設定する方が便利です。

オプションの ResourceDictionary タグは、Resources タグの子として含めることができます。

その後、リソースは、StaticResource XAML マークアップ拡張を使用して HorizontalOptions および VerticalOptionsプロパティを設定することにより、Button オブジェクトで使用できます。

<Button Text="Do this!"
        HorizontalOptions="{StaticResource horzOptions}"
        VerticalOptions="{StaticResource vertOptions}"
        BorderWidth="3"
        Rotation="-15"
        TextColor="Red"
        FontSize="24" />

StaticResource マークアップ拡張は常に中かっこで区切られ、ディクショナリ キーが含まれます。 名前 StaticResource が、.NET MAUI でもサポートされている DynamicResource とこれを区別します。 DynamicResource は、ランタイムに変更される可能性のある値に関連付けられたディクショナリ キー用です。一方、StaticResource は、ページ上の要素が構築されると、ディクショナリから要素に 1 回だけアクセスします。 XAML パーサーは StaticResource マークアップ拡張を検出するたびに、ビジュアル ツリーを検索し、そのキーを含む最初の ResourceDictionary を使用します。

BorderWidthRotationFontSize プロパティの場合は、ディクショナリでダブルを格納する必要があります。 XAML は、x:Doublex:Int32 のような一般的なデータ型のタグを簡単に定義します。

<ContentPage.Resources>
        <LayoutOptions x:Key="horzOptions"
                       Alignment="Center" />
        <LayoutOptions x:Key="vertOptions"
                       Alignment="Center" />
        <x:Double x:Key="borderWidth">3</x:Double>
        <x:Double x:Key="rotationAngle">-15</x:Double>
        <x:Double x:Key="fontSize">24</x:Double>        
</ContentPage.Resources>

これらの追加の 3 つのリソースは、LayoutOptions 値と同じ方法で参照できます。

<Button Text="Do this!"
        HorizontalOptions="{StaticResource horzOptions}"
        VerticalOptions="{StaticResource vertOptions}"
        BorderWidth="{StaticResource borderWidth}"
        Rotation="{StaticResource rotationAngle}"
        TextColor="Red"
        FontSize="{StaticResource fontSize}" />

Color 型のリソースの場合、これらの型の属性を直接割り当てるときに使用するものと同じ文字列表現を使用できます。 .NET MAUI に含まれる型コンバーターは、リソースの作成時に呼び出されます。 また、リソース ディクショナリ内の OnPlatform クラスを使用して、プラットフォームのさまざまな値を定義することもできます。 次の例では、このクラスを使用してさまざまなテキストの色を設定します。

<OnPlatform x:Key="textColor"
            x:TypeArguments="Color">
    <On Platform="iOS" Value="Red" />
    <On Platform="Android" Value="Aqua" />
</OnPlatform>

OnPlatform リソースはディクショナリ内のオブジェクトである x:TypeArguments 属性を取得し、ジェネリック クラスである x:Key 属性を取得します。 iOSおよびAndroid属性は、オブジェクトの初期化時に Color 値に変換されます。

次の例は、6 つの共有値にアクセスする 3 つのボタンを示しています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SharedResourcesPage"
             Title="Shared Resources Page">
    <ContentPage.Resources>
        <LayoutOptions x:Key="horzOptions"
                       Alignment="Center" />
        <LayoutOptions x:Key="vertOptions"
                       Alignment="Center" />
        <x:Double x:Key="borderWidth">3</x:Double>
        <x:Double x:Key="rotationAngle">-15</x:Double>
        <x:Double x:Key="fontSize">24</x:Double>    
        <OnPlatform x:Key="textColor"
                    x:TypeArguments="Color">
            <On Platform="iOS" Value="Red" />
            <On Platform="Android" Value="Aqua" />
            <On Platform="WinUI" Value="#80FF80" />
        </OnPlatform>
    </ContentPage.Resources>

    <StackLayout>
        <Button Text="Do this!"
                HorizontalOptions="{StaticResource horzOptions}"
                VerticalOptions="{StaticResource vertOptions}"
                BorderWidth="{StaticResource borderWidth}"
                Rotation="{StaticResource rotationAngle}"
                TextColor="{StaticResource textColor}"
                FontSize="{StaticResource fontSize}" />
        <Button Text="Do that!"
                HorizontalOptions="{StaticResource horzOptions}"
                VerticalOptions="{StaticResource vertOptions}"
                BorderWidth="{StaticResource borderWidth}"
                Rotation="{StaticResource rotationAngle}"
                TextColor="{StaticResource textColor}"
                FontSize="{StaticResource fontSize}" />
        <Button Text="Do the other thing!"
                HorizontalOptions="{StaticResource horzOptions}"
                VerticalOptions="{StaticResource vertOptions}"
                BorderWidth="{StaticResource borderWidth}"
                Rotation="{StaticResource rotationAngle}"
                TextColor="{StaticResource textColor}"
                FontSize="{StaticResource fontSize}" />
    </StackLayout>
</ContentPage>

次のスクリーンショットは、一貫性のあるスタイルを確認しています。

スタイル付きコントロールのスクリーンショット。

ページの上部に Resources コレクションを定義するのが一般的ですが、ページ上の他の要素に Resources コレクションを含めることができます。 たとえば、次の例は、StackLayout に追加されたリソースを示しています。

<StackLayout>
    <StackLayout.Resources>
        <Color x:Key="textColor">Blue</Color>
    </StackLayout.Resources>
    ...
</StackLayout>

リソース ディクショナリに格納されるオブジェクトの最も一般的な型の 1 つは、プロパティ設定のコレクションを定義する .NET MAUI Style です。 スタイルの詳細については、「XAML を使用したスタイル アプリ」を参照してください。

リソース ディクショナリの目的は、オブジェクトを共有することです。 そのため、リソース ディクショナリで Label または Button のようなコントロールを配置しても意味がありません。 同じインスタンスをページで 2 回表示することはできないため、ビジュアル要素を共有できません。

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

StaticResource マークアップ拡張に加えて、x:Static マークアップ拡張もあります。 ただし、StaticResource はリソース ディクショナリからオブジェクトを返しますが、x:Static は公開用静的フィールド、公開用静的プロパティ、公開用定数フィールド、または列挙型メンバーにアクセスします。

StaticResourceマークアップ拡張は、リソース ディクショナリを定義する XAML 実装でサポートされていますが、x:Staticx プレフィックスから明らかなように XAML の組み込み部分です。

次の例では、x:Static が静的フィールドと列挙型メンバーを明示的に参照する方法を示します。

<Label Text="Hello, XAML!"
       VerticalOptions="{x:Static LayoutOptions.Start}"
       HorizontalTextAlignment="{x:Static TextAlignment.Center}"
       TextColor="{x:Static Colors.Aqua}" />

x:Static マークアップ拡張の主な用途は、独自のコードから静的フィールドまたはプロパティを参照することです。 たとえば、アプリ全体の複数のページで使用する一部の静的フィールドを含む AppConstants クラスを次に示します。

namespace XamlSamples
{
    static class AppConstants
    {
        public static readonly Color BackgroundColor = Colors.Aqua;
        public static readonly Color ForegroundColor = Colors.Brown;
    }
}

XAML ファイルでこのクラスの静的フィールドを参照するには、XML 名前空間宣言を使用して、このファイルが配置されている場所を示す必要があります。 追加の XML 名前空間宣言ごとに、新しいプレフィックスが定義されます。 AppConstants のようなルート アプリ名前空間のローカル クラスにアクセスするには、プレフィックス local を使用できます。 名前空間宣言は、CLR (共通言語ランタイム) 名前空間名 (.NET 名前空間名とも呼ばれます) を示す必要があります。これは、C# namespace 定義または using ディレクティブに表示される名前です。

xmlns:local="clr-namespace:XamlSamples"

.NET 名前空間の XML 名前空間宣言を定義することもできます。 たとえば、これは netstandard アセンブリ内にある標準 .NET System 名前空間の sys プレフィックスを次に示します。 これは別のアセンブリなので、アセンブリ名も指定する必要があります (この場合は netstandard ):

xmlns:sys="clr-namespace:System;assembly=netstandard"

キーワード clr-namespace の後にコロン、.NET 名前空間名、セミコロン、キーワード assembly、等号、アセンブリ名が続きます。

その後、XML 名前空間を宣言すると、静的フィールドを使用できます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="XamlSamples.StaticConstantsPage"
             Title="Static Constants Page"
             Padding="5,25,5,0">
    <StackLayout>
       <Label Text="Hello, XAML!"
              TextColor="{x:Static local:AppConstants.BackgroundColor}"
              BackgroundColor="{x:Static local:AppConstants.ForegroundColor}"
              FontAttributes="Bold"
              FontSize="30"
              HorizontalOptions="Center" />
      <BoxView WidthRequest="{x:Static sys:Math.PI}"
               HeightRequest="{x:Static sys:Math.E}"
               Color="{x:Static local:AppConstants.ForegroundColor}"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand"
               Scale="100" />
    </StackLayout>
</ContentPage>

この例では、BoxView ディメンションは Math.PIMath.E に設定されていますが、100 倍にスケーリングできます。

x:Static マークアップ拡張を使用するコントロールのスクリーンショット。

他の XAML マークアップ拡張

いくつかのマークアップ拡張は XAML に組み込まれており、.NET MAUI XAML でサポートされています。 これらの一部はあまり使用されませんが、必要な場合は不可欠です。

  • プロパティに既定で null 以外の値があり、それを null に設定する場合は、{x:Null} マークアップ拡張に設定します。
  • プロパティが Type 型の場合は、マークアップ拡張 {x:Type someClass} を使用して Type オブジェクトに割り当てることができます。
  • x:Array マークアップ拡張を使用して、XAML で配列を定義できます。 このマークアップ拡張には、配列内の要素の型を示す、Type という名前の必須の属性があります。

XAML マークアップ拡張の詳細については、「XAML マークアップ拡張の使用」を参照してください。

次のステップ

.NET MAUI データ バインディングを使用すると、2 つのオブジェクトのプロパティをリンクできるため、一方のオブジェクトを変更すると、もう一方のオブジェクトが変更されます。