次の方法で共有


XAML マークアップ拡張の作成

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

開発者レベルでは、.NET マルチプラットフォーム アプリ UI (.NET MAUI) XAML マークアップ拡張は、IMarkupExtension<T> または IMarkupExtension インターフェイスを実装するクラスです。 IMarkupExtension または IMarkupExtension<T> から独自のカスタム XAML マークアップ拡張を定義することもできます。 マークアップ拡張機能が特定の型の値を取得する場合は、ジェネリック フォームを使用します。 これは、複数の .NET MAUI マークアップ拡張機能がある場合です。

  • TypeExtension は、IMarkupExtension<Type> から派生します
  • ArrayExtension は、IMarkupExtension<Array> から派生します
  • DynamicResourceExtension は、IMarkupExtension<DynamicResource> から派生します
  • BindingExtension は、IMarkupExtension<BindingBase> から派生します

IMarkupExtension または IMarkupExtension<T> を実装するすべてのクラスには、RequireServiceAttribute または AcceptEmptyServiceProviderAttribute で注釈を付ける必要があります。 詳細については、「サービス プロバイダー」をご覧ください。

2 つの IMarkupExtension インターフェイスは、ProvideValue という名前のそれぞれ 1 つのメソッドのみを定義します。

public interface IMarkupExtension
{
    object ProvideValue(IServiceProvider serviceProvider);
}

public interface IMarkupExtension<out T> : IMarkupExtension
{
    new T ProvideValue(IServiceProvider serviceProvider);
}

IMarkupExtension<T>IMarkupExtension から派生し、ProvideValuenew キーワードが含まれているので、両方の ProvideValue メソッドが含まれます。

多くの場合、XAML マークアップ拡張は戻り値に寄与するプロパティを定義し、 ProvideValue メソッドには IServiceProvider 型の 1 つの引数があります。 サービス プロバイダーの詳細については、「サービス プロバイダー」を参照してください。

マークアップ拡張を作成する

次の XAML マークアップ拡張機能は、独自のマークアップ拡張を作成する方法を示しています。 これにより、色相、彩度、および光度の各コンポーネントを使用して Color 値を構築できます。 これは、色の 4 つのコンポーネントの 4 つのプロパティを定義します。1 に初期化されるアルファ コンポーネントも含まれます。 このクラスは、IMarkupExtension<Color> から派生し、Color 戻り値を示します。

public class HslColorExtension : IMarkupExtension<Color>
{
    public float H { get; set; }
    public float S { get; set; }
    public float L { get; set; }
    public float A { get; set; } = 1.0f;

    public Color ProvideValue(IServiceProvider serviceProvider)
    {
        return Color.FromHsla(H, S, L, A);
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return (this as IMarkupExtension<Color>).ProvideValue(serviceProvider);
    }
}
[AcceptEmptyServiceProvider]
public class HslColorExtension : IMarkupExtension<Color>
{
    public float H { get; set; }
    public float S { get; set; }
    public float L { get; set; }
    public float A { get; set; } = 1.0f;

    public Color ProvideValue(IServiceProvider serviceProvider)
    {
        return Color.FromHsla(H, S, L, A);
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return (this as IMarkupExtension<Color>).ProvideValue(serviceProvider);
    }
}

このマークアップ拡張機能は、サービス プロバイダーからのサービスを使用しないため、AcceptEmptyServiceProviderAttribute で注釈を付けられます。 詳細については、「サービス プロバイダー」をご覧ください。

IMarkupExtension<T>IMarkupExtension から派生するため、クラスには 2 つの ProvideValue メソッドを含める必要があります。1 つは Color を返し、もう 1 つは object を返しますが、2 番目のメソッドは最初のメソッドを呼び出すことができます。

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

次の XAML は、BoxView の色を指定するために HslColorExtension の呼び出しで使用できるさまざまな方法を示しています。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MarkupExtensions"
             x:Class="MarkupExtensions.HslColorDemoPage"
             Title="HSL Color Demo">
    <ContentPage.Resources>
        <Style TargetType="BoxView">
            <Setter Property="WidthRequest" Value="80" />
            <Setter Property="HeightRequest" Value="80" />
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="VerticalOptions" Value="Center" />
        </Style>
    </ContentPage.Resources>

    <StackLayout>
        <BoxView>
            <BoxView.Color>
                <local:HslColorExtension H="0" S="1" L="0.5" A="1" />
            </BoxView.Color>
        </BoxView>
        <BoxView>
            <BoxView.Color>
                <local:HslColor H="0.33" S="1" L="0.5" />
            </BoxView.Color>
        </BoxView>
        <BoxView Color="{local:HslColorExtension H=0.67, S=1, L=0.5}" />
        <BoxView Color="{local:HslColor H=0, S=0, L=0.5}" />
        <BoxView Color="{local:HslColor A=0.5}" />
    </StackLayout>
</ContentPage>

この例では、HslColorExtension が XML タグで、4 つのプロパティが属性として設定されているものの、中かっこの間に表示される場合、4 つのプロパティは引用符なしでコンマで区切られます。 H の既定値は SL は 0、Aは 1 なので、既定値に設定する場合は、これらのプロパティを省略できます。 最後の例では、光度が 0 で、通常は黒になりますが、アルファ チャネルが 0.5 なので半分透明になり、ページの白い背景に対して灰色で表示されています。

HSL カラー デモ。

サービス プロバイダー

IServiceProvider 引数を ProvideValue に対して使用すると、XAML マークアップ拡張機能は、使用されている XAML ファイルに関するデータにアクセスできるようになります。 たとえば、IProvideValueTarget サービスを使用すると、マークアップ拡張機能が適用されているオブジェクトに関するデータを取得できます。

IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

IProvideValueTarget インターフェイスは 2 つのプロパティ、TargetObjectTargetProperty を定義します。 この情報が HslColorExtension クラスで取得される場合、TargetObjectBoxView で、TargetPropertyBoxViewColor プロパティです。 これは、XAML マークアップ拡張機能が設定されているプロパティです。

IMarkupExtension または IMarkupExtension<T> を実装するすべてのクラスには、RequireServiceAttribute または AcceptEmptyServiceProviderAttribute で注釈を付ける必要があります。

  • ProvideValue メソッドで serviceProvider.GetService(typeof(T)) を使用するたびに、クラスに [RequireService(typeof(T))] で注釈を付ける必要があります。

    [RequireService([typeof(IReferenceProvider), typeof(IProvideValueTarget)])]
    public class MyMarkupExtension : IMarkupExtension
    {
        public object ProvideValue(IServiceProvider serviceProvider)
        {
            ...
            var referenceProvider = serviceProvider.GetService<IReferenceProvider>();
            var valueProvider = serviceProvider.GetService<IProvideValueTarget>() as IProvideParentValues
                                    ?? throw new ArgumentException("serviceProvider does not provide an IProvideValueTarget");
            ...
        }
    }
    
  • マークアップ拡張機能でサービス プロバイダーのサービスが使用されていない場合は、クラスに [AcceptEmptyServiceProvider] で注釈を付ける必要があります。

これらの注釈は、より効率的なコードの生成を可能にする XAML コンパイラを最適化するために必要です。これにより、アプリのサイズを小さくし、実行時のパフォーマンスを向上させることができます。