Freigeben über


Erstellen von XAML-Markup-Erweiterungen

Beispiel durchsuchen.Durchsuchen Sie das Beispiel

Auf Entwicklerebene ist eine .NET Multi-Platform App UI (.NET MAUI) XAML Markup-Erweiterung eine Klasse, die die Schnittstelle IMarkupExtension oder IMarkupExtension<T> implementiert. Es ist auch möglich, eigene XAML-Markup-Erweiterungen zu definieren, indem man von IMarkupExtension oder IMarkupExtension<T> ableitet. Verwenden Sie die generische Form, wenn die Markup-Erweiterung einen Wert eines bestimmten Typs erhält. Dies ist bei mehreren der .NET MAUI Markup-Erweiterungen der Fall:

  • TypeExtension wird von IMarkupExtension<Type> abgeleitet
  • ArrayExtension wird von IMarkupExtension<Array> abgeleitet
  • DynamicResourceExtension wird von IMarkupExtension<DynamicResource> abgeleitet
  • BindingExtension wird von IMarkupExtension<BindingBase> abgeleitet

Alle Klassen, die IMarkupExtension oder IMarkupExtension<T> implementieren, müssen entweder mit RequireServiceAttribute oder AcceptEmptyServiceProviderAttribute kommentiert werden. Weitere Informationen finden Sie unter Dienstanbieter.

Die beiden IMarkupExtension-Schnittstellen definieren jeweils nur eine Methode, die ProvideValue genannt wird:

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

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

Da IMarkupExtension<T> von IMarkupExtension abgeleitet ist und das Schlüsselwort new auf ProvideValue enthält, enthält sie beide ProvideValue Methoden.

Häufig definieren XAML-Markup-Erweiterungen Eigenschaften, die zum Rückgabewert beitragen, und die Methode ProvideValue weist ein einzelnes Argument vom Typ IServiceProvider auf. Weitere Informationen über Dienstanbieter finden Sie unter Dienstanbieter.

Erstellen einer Markup-Erweiterung

Die folgende XAML-Markup-Erweiterung zeigt, wie Sie Ihre eigene Markup-Erweiterung erstellen können. Sie ermöglicht es Ihnen, einen Color-Wert aus den Komponenten Farbton, Sättigung und Helligkeit zu konstruieren. Sie definiert vier Eigenschaften für die vier Komponenten der Farbe, einschließlich einer Alphakomponente, die auf 1 initialisiert wird. Die Klasse leitet sich von IMarkupExtension<Color> ab, um einen Color Rückgabewert anzugeben:

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);
    }
}

Diese Markup-Erweiterung ist mit AcceptEmptyServiceProviderAttribute gekennzeichnet, da sie keinen Dienst des Dienstanbieters verwendet. Weitere Informationen finden Sie unter Dienstanbieter.

Da IMarkupExtension<T> von IMarkupExtension abgeleitet ist, muss die Klasse zwei ProvideValue-Methoden enthalten, eine, die ein Color zurückgibt, und eine, die ein object zurückgibt, aber die zweite Methode kann die erste Methode aufrufen.

Verwenden einer Markup-Erweiterung

Die folgende XAML demonstriert eine Vielzahl von Ansätzen, die verwendet werden können, um die HslColorExtension aufzurufen, um die Farbe für ein BoxView anzugeben:

<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>

Wenn HslColorExtension in diesem Beispiel ein XML-Tag ist, werden die vier Eigenschaften als Attribute festgelegt, aber wenn es zwischen geschweiften Klammern steht, werden die vier Eigenschaften durch Kommas ohne Anführungszeichen getrennt. Die Standardwerte für H, S und L sind 0, und der Standardwert von A ist 1, sodass diese Eigenschaften weggelassen werden können, wenn sie auf Standardwerte gesetzt werden sollen. Das letzte Beispiel zeigt ein Beispiel, bei dem die Helligkeit 0 ist, was normalerweise Schwarz ergibt, aber der Alphakanal 0,5 ist, sodass es halb transparent ist und vor dem weißen Hintergrund der Seite grau erscheint:

HSL-Farbdemo.

Dienstanbieter

Durch die Verwendung des IServiceProvider-Arguments für ProvideValue können XAML-Markup-Erweiterungen Zugriff auf Daten über die XAML-Datei erhalten, in der sie verwendet werden. Mit dem Dienst IProvideValueTarget können Sie zum Beispiel Daten über das Objekt abrufen, auf das die Markup-Erweiterung angewendet wird:

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

Die IProvideValueTarget-Schnittstelle definiert zwei Eigenschaften, TargetObject und TargetProperty. Wenn diese Information in der Klasse HslColorExtension erhalten wird, ist TargetObject die BoxView und TargetProperty die Color Eigenschaft von BoxView. Dies ist die Eigenschaft, für die die XAML-Markup-Erweiterung festgelegt wurde.

Alle Klassen, die IMarkupExtension oder IMarkupExtension<T> implementieren, müssen entweder mit RequireServiceAttribute oder AcceptEmptyServiceProviderAttribute kommentiert werden:

  • Für jede Verwendung von serviceProvider.GetService(typeof(T)) in der ProvideValue-Methode sollte die Klasse mit [RequireService(typeof(T))] kommentiert werden:

    [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");
            ...
        }
    }
    
  • Wenn die Markuperweiterung keinen Dienst des Dienstanbieters verwendet, sollte die Klasse mit [AcceptEmptyServiceProvider] kommentiert werden.

Diese Anmerkungen sind aufgrund einer XAML-Compileroptimierung erforderlich, die die Generierung von effizienterem Code ermöglicht, wodurch die App-Größe reduziert und die Laufzeitleistung verbessert wird.