Vytváření rozšíření značek XAML
Na programové úrovni je rozšíření značek XAML třída, která implementuje IMarkupExtension
nebo IMarkupExtension<T>
rozhraní. Zdrojový kód standardních rozšíření značek popsaných níže můžete prozkoumat v adresáři Xamarin.Forms MarkupExtensions úložiště GitHub.
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 Xamarin.Forms rozšířeními značek:
TypeExtension
odvozuje zIMarkupExtension<Type>
ArrayExtension
odvozuje zIMarkupExtension<Array>
DynamicResourceExtension
odvozuje zIMarkupExtension<DynamicResource>
BindingExtension
odvozuje zIMarkupExtension<BindingBase>
ConstraintExpression
odvozuje zIMarkupExtension<Constraint>
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 velmi často definují vlastnosti, které přispívají k návratové hodnotě. (Zjevná výjimka je NullExtension
, v níž ProvideValue
se jednoduše vrátí null
.) Metoda ProvideValue
má jeden argument typu IServiceProvider
, který bude popsán dále v tomto článku.
Rozšíření značek pro určení barvy
Následující rozšíření značek XAML 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 double H { set; get; }
public double S { set; get; }
public double L { set; get; }
public double A { set; get; } = 1.0;
public Color ProvideValue(IServiceProvider serviceProvider)
{
return Color.FromHsla(H, S, L, A);
}
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return (this as IMarkupExtension<Color>).ProvideValue(serviceProvider);
}
}
Vzhledem k tomu IMarkupExtension<T>
, odvozuje z IMarkupExtension
, třída musí obsahovat dvě ProvideValue
metody, jeden, který vrací Color
a druhý, který vrací object
, ale druhá metoda může jednoduše volat první metodu.
Stránka Ukázka barvy HSL ukazuje různé způsoby, jak HslColorExtension
se může zobrazit v souboru XAML a určit barvu pro BoxView
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.HslColorDemoPage"
Title="HSL Color Demo">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="BoxView">
<Setter Property="WidthRequest" Value="80" />
<Setter Property="HeightRequest" Value="80" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
</ResourceDictionary>
</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>
Všimněte si, že když HslColorExtension
je značka XML, jsou č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:
Rozšíření značek pro přístup k rastrovým obrázkům
Argumentem ProvideValue
je objekt, který implementuje IServiceProvider
rozhraní, které je definováno v oboru názvů .NET System
. Toto rozhraní má jeden člen, metodu pojmenovanou GetService
argumentem Type
.
Níže ImageResourceExtension
uvedená třída ukazuje jedno možné použití a GetService
získání objektu IServiceProvider
IXmlLineInfoProvider
, který může poskytnout informace o řádcích a znakech označující, kde byla zjištěna konkrétní chyba. V tomto případě je vyvolána výjimka, pokud Source
vlastnost nebyla nastavena:
[ContentProperty("Source")]
class ImageResourceExtension : IMarkupExtension<ImageSource>
{
public string Source { set; get; }
public ImageSource ProvideValue(IServiceProvider serviceProvider)
{
if (String.IsNullOrEmpty(Source))
{
IXmlLineInfoProvider lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
IXmlLineInfo lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
throw new XamlParseException("ImageResourceExtension requires Source property to be set", lineInfo);
}
string assemblyName = GetType().GetTypeInfo().Assembly.GetName().Name;
return ImageSource.FromResource(assemblyName + "." + Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
}
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return (this as IMarkupExtension<ImageSource>).ProvideValue(serviceProvider);
}
}
ImageResourceExtension
je užitečné, když soubor XAML potřebuje získat přístup k souboru obrázku uloženému jako vložený prostředek v projektu knihovny .NET Standard. Používá Source
vlastnost k volání statické ImageSource.FromResource
metody. Tato metoda vyžaduje plně kvalifikovaný název prostředku, který se skládá z názvu sestavení, názvu složky a názvu souboru odděleného tečkami. Druhý argument metody ImageSource.FromResource
poskytuje název sestavení a je vyžadován pouze pro sestavení vydané verze v UPW. Bez ohledu na to, ImageSource.FromResource
musí být volána ze sestavení, které obsahuje bitmapu, což znamená, že toto rozšíření prostředků XAML nemůže být součástí externí knihovny, pokud obrázky nejsou také v této knihovně. (Viz Další informace o přístupu k bitmapám uloženým jako vložené prostředky najdete v článku Vložené obrázky .)
Ačkoli ImageResourceExtension
vyžaduje Source
, aby byla vlastnost nastavena, Source
vlastnost je uvedena v atributu jako vlastnost obsahu třídy. To znamená, že Source=
část výrazu ve složených závorkách se dá vynechat. Na stránce Image
Ukázka prostředku obrázku načítají prvky dva obrázky pomocí názvu složky a názvu souboru odděleného tečkami:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.ImageResourceDemoPage"
Title="Image Resource Demo">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Source="{local:ImageResource Images.SeatedMonkey.jpg}"
Grid.Row="0" />
<Image Source="{local:ImageResource Images.FacePalm.jpg}"
Grid.Row="1" />
</Grid>
</ContentPage>
Tady je spuštěný program:
Poskytovatelé služeb
Rozšíření značek XAML můžou pomocí argumentu IServiceProvider
ProvideValue
získat přístup k užitečným informacím o souboru XAML, ve kterém se používají. Pokud ale chcete argument použít IServiceProvider
úspěšně, potřebujete vědět, jaký druh služeb jsou k dispozici v konkrétních kontextech. Nejlepší způsob, jak tuto funkci pochopit, je prozkoumání zdrojového kódu existujících rozšíření značek XAML ve složce MarkupExtensions v Xamarin.Forms úložišti na GitHubu. Mějte na paměti, že některé typy služeb jsou interní pro Xamarin.Forms.
V některých rozšířeních značek XAML může být tato služba užitečná:
IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
Rozhraní IProvideValueTarget
definuje dvě vlastnosti TargetObject
a TargetProperty
. Pokud jsou tyto informace získány ImageResourceExtension
ve třídě, TargetObject
je Image
a TargetProperty
je BindableProperty
objekt pro Source
vlastnost Image
. Toto je vlastnost, pro kterou bylo nastaveno rozšíření značek XAML.
Volání GetService
s argumentem typeof(IProvideValueTarget)
ve skutečnosti vrátí objekt typu SimpleValueTargetProvider
, který je definován v Xamarin.Forms.Xaml.Internals
oboru názvů. Pokud přetypujete návratovou GetService
hodnotu tohoto typu, můžete také získat přístup k ParentObjects
vlastnosti, což je pole obsahující Image
prvek, Grid
nadřazený prvek a ImageResourceDemoPage
nadřazený objekt Grid
.
Závěr
Rozšíření značek XAML hrají zásadní roli v XAML tím, že rozšiřují schopnost nastavit atributy z různých zdrojů. Navíc pokud existující rozšíření značek XAML neposkytují přesně to, co potřebujete, můžete také napsat vlastní.