Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
На программном уровне расширение разметки XAML — это класс, реализующий IMarkupExtension или IMarkupExtension<T> интерфейс. Исходный код стандартных расширений разметки, описанных ниже в каталоге Xamarin.Forms MarkupExtensions репозитория GitHub.
Кроме того, можно определить собственные расширения разметки XAML, производные от IMarkupExtension или IMarkupExtension<T>. Используйте универсальную форму, если расширение разметки получает значение определенного типа. Это касается нескольких Xamarin.Forms расширений разметки:
TypeExtensionпроисходит отIMarkupExtension<Type>.ArrayExtensionпроисходит отIMarkupExtension<Array>.DynamicResourceExtensionпроисходит отIMarkupExtension<DynamicResource>.BindingExtensionпроисходит отIMarkupExtension<BindingBase>.ConstraintExpressionпроисходит отIMarkupExtension<Constraint>.
Два IMarkupExtension интерфейса определяют только один метод с именем ProvideValue:
public interface IMarkupExtension
{
object ProvideValue(IServiceProvider serviceProvider);
}
public interface IMarkupExtension<out T> : IMarkupExtension
{
new T ProvideValue(IServiceProvider serviceProvider);
}
Так как IMarkupExtension<T> он является производным от IMarkupExtension ключевого слова и включает ключевое new слово в ProvideValue, он содержит оба ProvideValue метода.
Очень часто расширения разметки XAML определяют свойства, которые вносят вклад в возвращаемое значение. (Очевидное исключение — это NullExtension, в котором ProvideValue просто возвращается null.) Метод ProvideValue имеет один аргумент типа IServiceProvider , который будет обсуждаться далее в этой статье.
Расширение разметки для указания цвета
Следующее расширение разметки XAML позволяет создавать Color значение с помощью компонентов оттенка, насыщенности и яркости. Он определяет четыре свойства для четырех компонентов цвета, включая альфа-компонент, инициализированный до 1. Класс является производным от IMarkupExtension<Color> указания возвращаемого Color значения:
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);
}
}
Так как IMarkupExtension<T> производный от IMarkupExtensionкласса должен содержаться два ProvideValue метода, одно Color возвращает и другое, которое возвращает object, но второй метод может просто вызвать первый метод.
На странице демонстрации цвета HSL показаны различные способы, которые могут отображаться в XAML-файле, чтобы HslColorExtension указать цвет для 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>
Обратите внимание, что при HslColorExtension использовании XML-тега четыре свойства задаются как атрибуты, но при отображении между фигурными скобками четыре свойства разделяются запятыми без кавычки. Значения по умолчанию для H, Sи L равны 0, а значение A по умолчанию равно 1, поэтому эти свойства могут быть опущены, если они задают значения по умолчанию. В последнем примере показан пример, в котором светимость составляет 0, что обычно приводит к черному цвету, но альфа-канал равен 0,5, поэтому он является полупрозрачным и отображается серым на белом фоне страницы:
Расширение разметки для доступа к растровым картам
Аргументом ProvideValue является объект, реализующий IServiceProvider интерфейс, который определен в пространстве имен .NET System . Этот интерфейс содержит один член, метод с именем GetService аргумента Type .
В ImageResourceExtension приведенном ниже классе показано одно возможное использование IServiceProvider и GetService получение IXmlLineInfoProvider объекта, который может предоставлять сведения о строке и символах, указывающих, где обнаружена определенная ошибка. В этом случае возникает исключение, если Source свойство не задано:
[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 полезно, если ФАЙЛ XAML должен получить доступ к файлу изображения, хранящейся в качестве внедренного ресурса в проекте библиотеки .NET Standard. Он использует Source свойство для вызова статического ImageSource.FromResource метода. Для этого метода требуется полное имя ресурса, состоящее из имени сборки, имени папки и имени файла, разделенного точками. Второй аргумент метода ImageSource.FromResource предоставляет имя сборки и требуется только для сборки выпуска в UWP. Независимо от того, следует вызывать из сборки, ImageSource.FromResource содержащей растровое изображение, что означает, что это расширение ресурса XAML не может быть частью внешней библиотеки, если изображения также не находятся в этой библиотеке. (См. раздел Дополнительные сведения о доступе к растровым изображениям, хранящимся в виде внедренных ресурсов.
Хотя ImageResourceExtension требуется Source задать свойство, Source свойство указывается в атрибуте в качестве свойства содержимого класса. Это означает, что Source= часть выражения в фигурных скобках может быть опущена. На странице "Демонстрация ресурсов изображения" элементы извлекает два изображения с помощью имени папки и имени файла, Image разделенного точками:
<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>
Вот работающая программа:
Поставщики услуг
С помощью аргумента IServiceProvider ProvideValueрасширения разметки XAML могут получить доступ к полезным сведениям о XAML-файле, в котором они используются. Но для успешного IServiceProvider использования аргумента необходимо знать, какие службы доступны в определенных контекстах. Лучший способ получить представление об этой функции заключается в изучении исходного кода существующих расширений разметки XAML в папке MarkupExtensions в Xamarin.Forms репозитории на GitHub. Помните, что некоторые типы служб являются внутренними Xamarin.Forms.
В некоторых расширениях разметки XAML эта служба может оказаться полезной:
IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
Интерфейс IProvideValueTarget определяет два свойства и TargetObject TargetProperty. При получении этих сведений ImageResourceExtension в классе является Image BindableProperty TargetProperty объектом для Source свойства . TargetObject Image Это свойство, в котором задано расширение разметки XAML.
Вызов GetService с аргументом typeof(IProvideValueTarget) фактически возвращает объект типа SimpleValueTargetProvider, который определяется в Xamarin.Forms.Xaml.Internals пространстве имен. При приведение возвращаемого значения GetService этого типа также можно получить к ParentObjects свойству, который является массивом, содержащим Image элемент, Grid родительский и ImageResourceDemoPage родительский элемент Grid.
Заключение
Расширения разметки XAML играют важную роль в XAML, расширяя возможность задавать атрибуты из различных источников. Кроме того, если существующие расширения разметки XAML не предоставляют точно необходимые компоненты, вы также можете написать собственные.

