Bölüm 2. Temel XAML Söz Dizimi

XAML çoğunlukla nesneleri örneklemek ve başlatmak için tasarlanmıştır. Ancak genellikle, özellikler kolayca XML dizeleri olarak temsil edilemeyen karmaşık nesnelere ayarlanmalıdır ve bazen bir sınıf tarafından tanımlanan özellikler bir alt sınıfta ayarlanmalıdır. Bu iki gereksinim, özellik öğelerinin ve ekli özelliklerin temel XAML söz dizimi özelliklerini gerektirir.

Özellik Öğeleri

XAML'de sınıfların özellikleri normalde XML öznitelikleri olarak ayarlanır:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large"
       TextColor="Aqua" />

Ancak, XAML'de özellik ayarlamanın alternatif bir yolu vardır. Bu alternatifi ile TextColordenemek için önce mevcut TextColor ayarı silin:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large" />

empty-element Label etiketini başlangıç ve bitiş etiketlerine ayırarak açın:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large">

</Label>

Bu etiketler içinde, sınıf adından ve noktayla ayrılmış bir özellik adından oluşan başlangıç ve bitiş etiketleri ekleyin:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large">
    <Label.TextColor>

    </Label.TextColor>
</Label>

Özellik değerini şu yeni etiketlerin içeriği olarak ayarlayın:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large">
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

Özelliği belirtmenin TextColor bu iki yolu işlevsel olarak eşdeğerdir, ancak aynı özelliğin iki yolunu kullanmaz çünkü bu, özelliği etkili bir şekilde iki kez ayarlayıp belirsiz olabilir.

Bu yeni söz dizimi ile bazı kullanışlı terminolojiler tanıtılabilir:

  • Label bir nesne öğesidir. XML öğesi olarak ifade edilen bir nesnedir Xamarin.Forms .
  • Text, VerticalOptionsve FontSize özellik öznitelikleridir. FontAttributes Bunlar Xamarin.Forms XML öznitelikleri olarak ifade edilen özelliklerdir.
  • Bu son kod parçacığında TextColor bir özellik öğesi haline geldi. Bu bir Xamarin.Forms özelliktir, ancak artık bir XML öğesidir.

Özellik öğelerinin tanımı ilk başta XML söz diziminin ihlali gibi görünebilir, ancak değildir. Noktanın XML'de özel bir anlamı yoktur. XML kod çözücüsü için Label.TextColor yalnızca normal bir alt öğedir.

Ancak XAML'de bu söz dizimi çok özeldir. Özellik öğelerinin kurallarından biri, etikette Label.TextColor başka hiçbir şeyin görünemebileceğidir. özelliğinin değeri her zaman özellik öğesi başlangıç ve bitiş etiketleri arasında içerik olarak tanımlanır.

Özellik öğesi söz dizimini birden fazla özellikte kullanabilirsiniz:

<Label Text="Hello, XAML!"
       VerticalOptions="Center">
    <Label.FontAttributes>
        Bold
    </Label.FontAttributes>
    <Label.FontSize>
        Large
    </Label.FontSize>
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

Veya tüm özellikler için özellik öğesi söz dizimini kullanabilirsiniz:

<Label>
    <Label.Text>
        Hello, XAML!
    </Label.Text>
    <Label.FontAttributes>
        Bold
    </Label.FontAttributes>
    <Label.FontSize>
        Large
    </Label.FontSize>
    <Label.TextColor>
        Aqua
    </Label.TextColor>
    <Label.VerticalOptions>
        Center
    </Label.VerticalOptions>
</Label>

İlk başta, özellik öğesi söz dizimi oldukça basit bir şey için gereksiz uzun soluklu bir değişim gibi görünebilir ve bu örneklerde kesinlikle böyledir.

Ancak, bir özelliğin değeri basit bir dize olarak ifade edilemeyecek kadar karmaşık olduğunda özellik öğesi söz dizimi temel hale gelir. Property-element etiketleri içinde başka bir nesnenin örneğini oluşturabilir ve özelliklerini ayarlayabilirsiniz. Örneğin, gibi VerticalOptions bir özelliği, özellik ayarlarıyla bir LayoutOptions değere açıkça ayarlayabilirsiniz:

<Label>
    ...
    <Label.VerticalOptions>
        <LayoutOptions Alignment="Center" />
    </Label.VerticalOptions>
</Label>

Başka bir örnek: ve Grid adlı RowDefinitions ColumnDefinitionsiki özelliği vardır. Bu iki özellik, ve ColumnDefinitionCollectionnesne koleksiyonları RowDefinition olan ve ColumnDefinition türündedirRowDefinitionCollection. Bu koleksiyonları ayarlamak için özellik öğesi söz dizimini kullanmanız gerekir.

Ve koleksiyonları için özellik öğesi etiketlerini gösteren bir GridDemoPage sınıf için XAML dosyasının RowDefinitions ColumnDefinitions başlangıcı aşağıdadır:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        ...
    </Grid>
</ContentPage>

Otomatik boyutlandırılmış hücreleri, piksel genişlik ve yüksekliklerindeki hücreleri ve yıldız ayarlarını tanımlamak için kısaltılmış söz dizimine dikkat edin.

İliştirilmiş Özellikler

ve koleksiyonlarının satır ve sütunları tanımlamak için RowDefinitions ColumnDefinitions özellik öğelerini gerektirdiğini gördünüzGrid. Ancak, programcının her alt öğesinin bulunduğu satır ve sütunu belirtmesinin Grid bir yolu da olmalıdır.

Her alt öğesinin Grid etiketinde, aşağıdaki öznitelikleri kullanarak bu alt öğeye ait satır ve sütunu belirtin:

  • Grid.Row
  • Grid.Column

Bu özniteliklerin varsayılan değerleri 0'dır. Ayrıca, bir alt öğenin şu özniteliklere sahip birden fazla satıra veya sütuna yayılıp yayılmayabileceğini de belirtebilirsiniz:

  • Grid.RowSpan
  • Grid.ColumnSpan

Bu iki özniteliğin varsayılan değerleri 1'tir.

GridDemoPage.xaml dosyasının tamamı aşağıdadır:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>

        <Label Text="Autosized cell"
               Grid.Row="0" Grid.Column="0"
               TextColor="White"
               BackgroundColor="Blue" />

        <BoxView Color="Silver"
                 HeightRequest="0"
                 Grid.Row="0" Grid.Column="1" />

        <BoxView Color="Teal"
                 Grid.Row="1" Grid.Column="0" />

        <Label Text="Leftover space"
               Grid.Row="1" Grid.Column="1"
               TextColor="Purple"
               BackgroundColor="Aqua"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

        <Label Text="Span two rows (or more if you want)"
               Grid.Row="0" Grid.Column="2" Grid.RowSpan="2"
               TextColor="Yellow"
               BackgroundColor="Blue"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

        <Label Text="Span two columns"
               Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
               TextColor="Blue"
               BackgroundColor="Yellow"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

        <Label Text="Fixed 100x100"
               Grid.Row="2" Grid.Column="2"
               TextColor="Aqua"
               BackgroundColor="Red"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

    </Grid>
</ContentPage>

Grid.Row 0 ve Grid.Column ayarları gerekli değildir, ancak genellikle netlik amacıyla dahil edilir.

Şöyle görünür:

Kılavuz Düzeni

Yalnızca söz diziminden bakıldığında, bu Grid.Row, Grid.Column, Grid.RowSpanve Grid.ColumnSpan öznitelikleri statik alanlar veya özellikleri Gridolarak görünür, ancak ilginç Grid bir şekilde , , ColumnRowSpanveya ColumnSpanadlı Rowhiçbir şey tanımlamaz.

Bunun yerine, Grid , , ColumnPropertyRowSpanPropertyve ColumnSpanPropertyadlı RowPropertydört bağlanabilir özellik tanımlar. Bunlar, ekli özellikler olarak bilinen özel bağlanabilir özellik türleridir. Sınıfı tarafından Grid tanımlanır, ancak öğesinin alt öğelerine Gridayarlanır.

Bu ekli özellikleri kodda kullanmak istediğinizde, Grid sınıfı , GetColumnve benzeri adlı SetRowstatik yöntemler sağlar. Ancak XAML'de bu ekli özellikler, basit özellik adları kullanılarak öğesinin Grid alt öğelerinde öznitelik olarak ayarlanır.

Ekli özellikler XAML dosyalarında her zaman bir sınıf ve noktayla ayrılmış bir özellik adı içeren öznitelikler olarak tanınabilir. Bunlar, bir sınıf tarafından tanımlandığından (bu örnekte, Grid) ekli özellikler olarak adlandırılır, ancak diğer nesnelere (bu örnekte öğesinin Gridalt öğeleri) eklenir. düzen sırasında, Grid her bir alt öğeyi nereye yerleştireceklerini bilmek için bu ekli özelliklerin değerlerini sorgulayabilir.

AbsoluteLayout sınıfı ve LayoutFlagsadlı LayoutBounds iki ekli özelliği tanımlar. Aşağıda, 'nin orantılı konumlandırma ve boyutlandırma özellikleri kullanılarak gerçekleştirilen bir dama tahtası deseni verilmiştir AbsoluteLayout:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.AbsoluteDemoPage"
             Title="Absolute Demo Page">

    <AbsoluteLayout BackgroundColor="#FF8080">
        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.33, 0, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="1, 0, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0, 0.33, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.67, 0.33, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.33, 0.67, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="1, 0.67, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0, 1, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.67, 1, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

  </AbsoluteLayout>
</ContentPage>

Ve işte burada:

Mutlak Düzen

Bunun gibi bir şey için XAML kullanmanın bilgeliğini sorgulayabilirsiniz. Kesinlikle, dikdörtgenin tekrarı ve düzenliliği LayoutBounds kodda daha iyi gerçekleştirilebileceğini gösterir.

Bu kesinlikle meşru bir konudur ve kullanıcı arabirimlerinizi tanımlarken kod ve işaretleme kullanımını dengeleme konusunda herhangi bir sorun yoktur. XAML'de bazı görselleri tanımlamak ve ardından arka planda kod dosyasının oluşturucusunu kullanarak döngülerde daha iyi oluşturulabilecek daha fazla görsel eklemek kolaydır.

İçerik Özellikleri

Önceki örneklerde , StackLayoutGridve AbsoluteLayout nesneleri öğesinin ContentPageözelliğine Content ayarlanır ve bu düzenlerin alt öğeleri aslında koleksiyondaki Children öğelerdir. Ancak bu Content ve Children özellikleri XAML dosyasında hiçbir yerde yoktur.

ve özelliklerini XamlPlusCode örneğinde olduğu gibi özellik öğeleri olarak kesinlikle ekleyebilirsinizContent:Children

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.XamlPlusCodePage"
             Title="XAML + Code Page">
    <ContentPage.Content>
        <StackLayout>
            <StackLayout.Children>
                <Slider VerticalOptions="CenterAndExpand"
                        ValueChanged="OnSliderValueChanged" />

                <Label x:Name="valueLabel"
                       Text="A simple Label"
                       FontSize="Large"
                       HorizontalOptions="Center"
                       VerticalOptions="CenterAndExpand" />

                <Button Text="Click Me!"
                      HorizontalOptions="Center"
                      VerticalOptions="CenterAndExpand"
                      Clicked="OnButtonClicked" />
            </StackLayout.Children>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Asıl soru şudur: Bu özellik öğeleri neden XAML dosyasında gerekli değildir ?

XAML'de kullanılmak üzere içinde tanımlanan Xamarin.Forms öğelerin sınıfında özniteliğinde bir özelliğin ContentProperty bayrakla işaretlenmesini sağlamak için izin verilir. Sınıfı çevrimiçi Xamarin.Forms belgelerde ararsanız ContentPage şu özniteliği görürsünüz:

[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage

Bu, özellik öğesi etiketlerinin Content gerekli olmadığı anlamına gelir. Başlangıç ve bitiş ContentPage etiketleri arasında görünen tüm XML içeriğinin özelliğine Content atandığı varsayılır.

StackLayout, Grid, AbsoluteLayoutve RelativeLayout tümü ' den Layout<View>türetilir ve belgelerde Xamarin.Forms ararsanız Layout<T> başka bir ContentProperty öznitelik görürsünüz:

[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout ...

Bu, düzenin içeriğinin açık Children özellik öğesi etiketleri olmadan koleksiyona Children otomatik olarak eklenmesini sağlar.

Diğer sınıflar da öznitelik tanımlarına sahiptir ContentProperty . Örneğin, içerik özelliği Label şeklindedir Text. Diğerleri için API belgelerine bakın.

OnPlatform ile Platform Farklılıkları

Tek sayfalı uygulamalarda, iOS durum çubuğunun Padding üzerine yazılmasını önlemek için sayfadaki özelliği ayarlamak yaygın bir durumdur. Kodda özelliğini şu amaçla kullanabilirsiniz Device.RuntimePlatform :

if (Device.RuntimePlatform == Device.iOS)
{
    Padding = new Thickness(0, 20, 0, 0);
}

ve On sınıflarını kullanarak OnPlatform XAML'de de benzer bir şey yapabilirsiniz. İlk olarak, sayfanın üst kısmındaki Padding özelliğin özellik öğelerini ekleyin:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>

    </ContentPage.Padding>
    ...
</ContentPage>

Bu etiketlerin içinde bir OnPlatform etiket ekleyin. OnPlatform genel bir sınıftır. Bu durumda Thickness, özelliğin türü olan genel tür bağımsız değişkenini Padding belirtmeniz gerekir. Neyse ki, adlı x:TypeArgumentsgenel bağımsız değişkenleri tanımlamak için özel olarak bir XAML özniteliği vardır. Bu, ayarladığınız özelliğin türüyle eşleşmelidir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">

        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

OnPlatform adlı bir nesneye Platforms IList On sahiptir. Bu özellik için özellik öğesi etiketlerini kullanın:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <OnPlatform.Platforms>

            </OnPlatform.Platforms>
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Şimdi öğeleri ekleyin On . Her biri için özelliğini ve Value özelliğini özelliği için işaretlemek üzere Thickness ayarlayınPlatform:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <OnPlatform.Platforms>
                <On Platform="iOS" Value="0, 20, 0, 0" />
                <On Platform="Android" Value="0, 0, 0, 0" />
                <On Platform="UWP" Value="0, 0, 0, 0" />
            </OnPlatform.Platforms>
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Bu işaretleme basitleştirilmiş olabilir. öğesinin OnPlatform içerik özelliğidir Platforms, bu nedenle bu özellik öğesi etiketleri kaldırılabilir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
            <On Platform="Android" Value="0, 0, 0, 0" />
            <On Platform="UWP" Value="0, 0, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Platform özelliği On türündedirIList<string>, bu nedenle değerler aynıysa birden çok platform ekleyebilirsiniz:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
            <On Platform="Android, UWP" Value="0, 0, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Android ve UWP varsayılan değerine ayarlandığından Padding, bu etiket kaldırılabilir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Bu, XAML'de platforma bağımlı Padding bir özellik ayarlamanın standart yoludur. Value Ayar tek bir dizeyle temsil edilemiyorsa, bunun için özellik öğelerini tanımlayabilirsiniz:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS">
                <On.Value>
                    0, 20, 0, 0
                </On.Value>
            </On>
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Not

İşaretlemeyi OnPlatform genişletme, XAML'de kullanıcı arabirimi görünümünü platforma göre özelleştirmek için de kullanılabilir. ve On sınıflarıyla aynı işlevselliği OnPlatform sağlar, ancak daha kısa bir gösterim sağlar. Daha fazla bilgi için bkz . OnPlatform biçimlendirme uzantısı.

Özet

Özellik öğeleri ve ekli özelliklerle, temel XAML söz diziminin çoğu oluşturulmuştur. Ancak, bazen bir kaynak sözlüğünden dolaylı bir şekilde nesnelere özellikler ayarlamanız gerekir. Bu yaklaşım sonraki bölüm olan Bölüm 3'te ele alınmıştır. XAML İşaretlemeyi Uzantıları.