Vytvoření rozšíření značek XAML
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 zIMarkupExtension<Type>
ArrayExtension
odvozuje zIMarkupExtension<Array>
DynamicResourceExtension
odvozuje zIMarkupExtension<DynamicResource>
BindingExtension
odvozuje zIMarkupExtension<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 S
na 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:
Poskytovatelé služeb
Pomocí argumentu IServiceProvider
mohou ProvideValue
rozšíř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))
vProvideValue
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.