Sdílet prostřednictvím


Vytvoření rozšíření značek XAML

Projděte si ukázku. Procházení ukázky

Na úrovni vývojáře je rozšíření značek XAML pro více platforem (.NET MAUI) .NET Multi-Platform App UI (.NET MAUI) třída, která implementuje IMarkupExtension rozhraní nebo IMarkupExtension<T> rozhraní. Je také možné definovat vlastní rozšíření značek XAML odvozením nebo IMarkupExtension IMarkupExtension<T>. Obecný formulář použijte, pokud rozšíření značek získá hodnotu určitého typu. Toto je případ s několika rozšířeními značek .NET MAUI:

  • TypeExtension odvozuje z IMarkupExtension<Type>
  • ArrayExtension odvozuje z IMarkupExtension<Array>
  • DynamicResourceExtension odvozuje z IMarkupExtension<DynamicResource>
  • BindingExtension odvozuje z IMarkupExtension<BindingBase>

Všechny třídy, které implementují IMarkupExtension nebo IMarkupExtension<T> musí být opatřeny poznámkami buď pomocí RequireServiceAttribute nebo AcceptEmptyServiceProviderAttribute. Další informace najdete v tématu Poskytovatelé služeb.

IMarkupExtension Obě rozhraní definují pouze jednu metodu s názvem ProvideValue:

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

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

Vzhledem k tomu, IMarkupExtension<T> že je odvozeno od IMarkupExtension klíčového slova a obsahuje klíčové new slovo on ProvideValue, obsahuje obě ProvideValue metody.

Rozšíření značek XAML často definují vlastnosti, které přispívají k návratové hodnotě, a ProvideValue metoda má jeden argument typu IServiceProvider. Další informace o poskytovateli služeb najdete v tématu Poskytovatelé služeb.

Vytvoření rozšíření značek

Následující rozšíření značek XAML ukazuje, jak vytvořit vlastní rozšíření značek. Umožňuje vytvořit Color hodnotu pomocí komponent odstínu, sytosti a světelnosti. Definuje čtyři vlastnosti pro čtyři součásti barvy, včetně alfa komponenty inicializované na hodnotu 1. Třída je odvozena od IMarkupExtension<Color> označení návratové Color hodnoty:

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

Toto rozšíření značek je opatřeno poznámkami AcceptEmptyServiceProviderAttribute , protože nepoužívá službu od poskytovatele služeb. Další informace najdete v tématu Poskytovatelé služeb.

Vzhledem k tomu IMarkupExtension<T> , odvozuje z IMarkupExtension, třída musí obsahovat dvě ProvideValue metody, jeden, který vrací a druhý, který vrací Color object, ale druhá metoda může volat první metodu.

Využití rozšíření značek

Následující XAML ukazuje různé přístupy, které lze použít k vyvolání HslColorExtension k určení barvy pro BoxView:

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

Pokud je v tomto příkladu HslColorExtension značka XML čtyři vlastnosti nastaveny jako atributy, ale když se zobrazí mezi složenými složenými závorkami, jsou čtyři vlastnosti odděleny čárkami bez uvozovek. Výchozí hodnoty pro H, a jsou L 0 a výchozí hodnota A je 1, takže tyto vlastnosti lze vynechat, pokud je chcete nastavit Sna výchozí hodnoty. Poslední příklad ukazuje příklad, ve kterém je světelnost 0, což obvykle vede k černému, ale alfa kanál je 0,5, takže je polovina průhledná a zobrazuje se šedá na bílém pozadí stránky:

Ukázka barvy HSL.

Poskytovatelé služeb

Pomocí argumentu IServiceProvider mohou ProvideValuerozšíření značek XAML získat přístup k datům o souboru XAML, ve kterém se používají. Služba například umožňuje načíst data o objektu, IProvideValueTarget na který se rozšíření značek vztahuje:

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

Rozhraní IProvideValueTarget definuje dvě vlastnosti TargetObject a TargetProperty. Pokud jsou tyto informace získány HslColorExtension ve třídě, TargetObject je a BoxView TargetProperty je Color vlastnost BoxView. Toto je vlastnost, pro kterou bylo nastaveno rozšíření značek XAML.

Všechny třídy, které implementují IMarkupExtension nebo IMarkupExtension<T> musí být opatřeny poznámkami buď pomocí AcceptEmptyServiceProviderAttributeRequireServiceAttribute

  • Pro každé použití serviceProvider.GetService(typeof(T)) v ProvideValue metodě by třída měla být opatřena poznámkami [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");
            ...
        }
    }
    
  • Pokud rozšíření značek nepoužívá žádnou službu od poskytovatele služeb, měla by být třída opatřena poznámkami [AcceptEmptyServiceProvider].

Tyto poznámky se vyžadují kvůli optimalizaci kompilátoru XAML, která umožňuje generování efektivnějšího kódu, což pomáhá snížit velikost aplikace a zlepšit výkon modulu runtime.