Aracılığıyla paylaş


XAML Biçimlendirme Uzantıları Oluşturma

Program düzeyinde, XAML işaretleme uzantısı veya IMarkupExtension<T> arabirimini IMarkupExtension uygulayan bir sınıftır. GitHub deposunun MarkupExtensions dizininde aşağıda açıklanan standart işaretleme uzantılarının Xamarin.Forms kaynak kodunu inceleyebilirsiniz.

veya IMarkupExtension<T>'den IMarkupExtension türeterek kendi özel XAML işaretleme uzantılarınızı da tanımlayabilirsiniz. İşaretlemeyi uzantısı belirli bir türde bir değer alırsa genel formu kullanın. Birkaç işaretleme uzantısında Xamarin.Forms bu durum söz konusudur:

  • TypeExtension Türetildiği IMarkupExtension<Type>
  • ArrayExtension Türetildiği IMarkupExtension<Array>
  • DynamicResourceExtension Türetildiği IMarkupExtension<DynamicResource>
  • BindingExtension Türetildiği IMarkupExtension<BindingBase>
  • ConstraintExpression Türetildiği IMarkupExtension<Constraint>

İki IMarkupExtension arabirim her biri adlı ProvideValuetek bir yöntem tanımlar:

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

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

'IMarkupExtension<T>den türetilir ve anahtar ProvideValuesözcüğünü içerdiğinden IMarkupExtension new her iki yöntemi de ProvideValue içerir.

XAML işaretleme uzantıları genellikle dönüş değerine katkıda bulunan özellikleri tanımlar. (Belirgin özel durum, içinde yalnızca nulldöndürdüğü ProvideValue şeklindedirNullExtension.) yöntemi, ProvideValue bu makalenin devamında ele alınacak tek bir tür IServiceProvider bağımsız değişkenine sahiptir.

Renk Belirtmek için İşaretleme Uzantısı

Aşağıdaki XAML işaretleme uzantısı ton, doygunluk ve parlaklık bileşenlerini kullanarak bir Color değer oluşturmanıza olanak tanır. Rengin dört bileşeni için, 1'e başlatılan bir alfa bileşeni de dahil olmak üzere dört özellik tanımlar. sınıfı, bir Color dönüş değeri belirtmek için öğesinden IMarkupExtension<Color> türetilir:

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> öğesinden IMarkupExtensiontüretildiği için sınıfı, biri döndürenColor, diğeri ise öğesini döndüren objectiki ProvideValue yöntem içermelidir, ancak ikinci yöntem yalnızca ilk yöntemi çağırabilir.

HSL Color Demo sayfası, bir XAML dosyasında xaml dosyasının HslColorExtension rengini belirtmek için BoxViewkullanılabilecek çeşitli yollar gösterir:

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

BIR XML etiketi olduğunda HslColorExtension , dört özelliğin öznitelik olarak ayarlandığına, ancak küme ayraçları arasında göründüğünde, dört özelliğin tırnak işareti olmadan virgülle ayrıldığına dikkat edin. , Sve L için Hvarsayılan değerler 0 ve varsayılan değeri A 1'dir, bu nedenle varsayılan değerlere ayarlanmasını istiyorsanız bu özellikler atlanabilir. Son örnekte parlaklığın 0 olduğu ve normalde siyah sonuç veren ancak alfa kanalının 0,5 olduğu, dolayısıyla yarı saydam olduğu ve sayfanın beyaz arka planında gri göründüğü bir örnek gösterilmektedir:

HSL Renk Tanıtımı

Bit Eşlemlere Erişmek için İşaretlemeyi Genişletme

bağımsız değişkeniProvideValue, .NET System ad alanında tanımlanan arabirimi uygulayan bir nesnedirIServiceProvider. Bu arabirimin bağımsız değişkeni olan adlı GetService bir yöntem olan bir Type üyesi vardır.

ImageResourceExtension Aşağıda gösterilen sınıf, belirli bir hatanın IServiceProvider GetService nerede algılandığını gösteren satır ve karakter bilgileri sağlayabilen bir IXmlLineInfoProvider nesne elde etmek için ve'nin olası bir kullanımını gösterir. Bu durumda, özellik ayarlanmadığında Source bir özel durum oluşur:

[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 bir XAML dosyasının .NET Standart kitaplık projesinde ekli kaynak olarak depolanan bir görüntü dosyasına erişmesi gerektiğinde yararlıdır. statik ImageSource.FromResource yöntemini çağırmak için özelliğini kullanırSource. Bu yöntem derleme adından, klasör adından ve noktalarla ayrılmış dosya adından oluşan tam kaynak adını gerektirir. yönteminin ImageSource.FromResource ikinci bağımsız değişkeni derleme adını sağlar ve yalnızca UWP'de yayın derlemeleri için gereklidir. Ne olursa olsun, ImageSource.FromResource bit eşlem içeren derlemeden çağrılmalıdır, yani bu XAML kaynak uzantısı, görüntüler de bu kitaplıkta olmadığı sürece bir dış kitaplığın parçası olamaz. (Bkz. Katıştırılmış kaynak olarak depolanan bit eşlemlere erişme hakkında daha fazla bilgi için Ekli Görüntüler makalesi.)

Özelliğinin Source ayarlanmasını gerektirse ImageResourceExtension de, özelliği sınıfın Source içerik özelliği olarak bir öznitelikte belirtilir. Bu, ifadenin Source= küme ayraçlarındaki bölümünün atlanabilir olduğu anlamına gelir. Görüntü Kaynağı Tanıtımı sayfasında, Image öğeler klasör adını ve dosya adını noktalarla ayırarak iki görüntü getirir:

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

Çalışan program şu şekildedir:

Görüntü Kaynağı Tanıtımı

Hizmet Sağlayıcılar

bağımsız değişkenini IServiceProvider ProvideValuekullanarak, XAML işaretleme uzantıları kullanıldıkları XAML dosyası hakkında yararlı bilgilere erişebilir. Ancak bağımsız değişkeni başarıyla kullanmak IServiceProvider için belirli bağlamlarda ne tür hizmetlerin kullanılabilir olduğunu bilmeniz gerekir. Bu özelliği anlamanın en iyi yolu, GitHub'daki depodaki MarkupExtensions klasöründeki mevcut XAML işaretleme uzantılarının Xamarin.Forms kaynak kodunu incelemektir. Bazı hizmet türlerinin için Xamarin.Formsdahili olduğunu unutmayın.

Bazı XAML işaretleme uzantılarında bu hizmet yararlı olabilir:

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

IProvideValueTarget Arabirimi iki özellik TargetObject tanımlar ve TargetProperty. Bu bilgiler sınıfında ImageResourceExtension elde edildiğinde, Image TargetObject ve TargetProperty özelliği Imageiçin Source bir BindableProperty nesnesidir. Bu, XAML işaretleme uzantısının ayarlandığı özelliktir.

GetService bağımsız değişkenine typeof(IProvideValueTarget) sahip çağrı, ad alanında Xamarin.Forms.Xaml.Internals tanımlanan türünde SimpleValueTargetProviderbir nesnesi döndürür. dönüş değerini GetService bu türe dönüştürürseniz öğesini, üst öğesini ve ImageResourceDemoPage üst Gridöğesini içeren Image Grid bir dizi olan bir özelliğe de erişebilirsinizParentObjects.

Sonuç

XAML işaretleme uzantıları, çeşitli kaynaklardan öznitelik ayarlama özelliğini genişleterek XAML'de önemli bir rol oynar. Ayrıca, mevcut XAML işaretleme uzantıları tam olarak ihtiyacınız olanı sağlamıyorsa, kendiniz de yazabilirsiniz.