2. část: Základní syntaxe XAML
XAML je většinou navržený pro vytváření instancí a inicializaci objektů. Často však musí být vlastnosti nastaveny na složité objekty, které nelze snadno reprezentovat jako řetězce XML, a někdy vlastnosti definované jednou třídou musí být nastaveny v podřízené třídě. Tyto dva požadavky vyžadují základní funkce syntaxe XAML elementů vlastností a připojených vlastností.
Elementy vlastností
V jazyce XAML jsou vlastnosti tříd obvykle nastaveny jako atributy XML:
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large"
TextColor="Aqua" />
Existuje však alternativní způsob, jak nastavit vlastnost v XAML. Pokud chcete vyzkoušet tuto alternativu TextColor
, odstraňte nejprve existující TextColor
nastavení:
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large" />
Otevřete značku prázdného elementu Label
tak, že ji oddělíte na počáteční a koncové značky:
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
</Label>
Do těchto značek přidejte počáteční a koncové značky, které se skládají z názvu třídy a názvu vlastnosti oddělené tečkou:
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
<Label.TextColor>
</Label.TextColor>
</Label>
Nastavte hodnotu vlastnosti jako obsah těchto nových značek, například takto:
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
<Label.TextColor>
Aqua
</Label.TextColor>
</Label>
Tyto dva způsoby, jak zadat TextColor
vlastnost, jsou funkčně ekvivalentní, ale nepoužívejte dva způsoby pro stejnou vlastnost, protože by efektivně nastavovala vlastnost dvakrát a může být nejednoznačná.
S touto novou syntaxí je možné zavést určitou praktickou terminologii:
Label
je objektový prvek. Jedná se o objekt vyjádřený Xamarin.Forms jako element XML.Text
,VerticalOptions
FontAttributes
aFontSize
jsou atributy vlastností. Jsou to Xamarin.Forms vlastnosti vyjádřené jako atributy XML.- V tomto posledním fragmentu kódu
TextColor
se stal elementem vlastnosti. Jedná se o Xamarin.Forms vlastnost, ale nyní se jedná o element XML.
Definice elementů vlastností se zpočátku může zdát porušení syntaxe XML, ale není to. Tečka nemá v XML žádný zvláštní význam. Dekodér Label.TextColor
XML je jednoduše normální podřízený prvek.
V jazyce XAML je ale tato syntaxe velmi zvláštní. Jedním z pravidel pro prvky vlastnosti je, že se ve značce nemůže objevit nic jiného Label.TextColor
. Hodnota vlastnosti je vždy definována jako obsah mezi počáteční a koncové značky prvku property.
Syntaxi elementu vlastnosti můžete použít u více než jedné vlastnosti:
<Label Text="Hello, XAML!"
VerticalOptions="Center">
<Label.FontAttributes>
Bold
</Label.FontAttributes>
<Label.FontSize>
Large
</Label.FontSize>
<Label.TextColor>
Aqua
</Label.TextColor>
</Label>
Nebo můžete použít syntaxi elementu property pro všechny vlastnosti:
<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>
Syntaxe elementu vlastností se zpočátku může zdát jako nepotřebná dlouho vinutá náhrada za něco poměrně jednoduchého a v těchto příkladech, která je jistě případem.
Syntaxe elementu property se však stává zásadní, pokud je hodnota vlastnosti příliš složitá, aby byla vyjádřena jako jednoduchý řetězec. V rámci značek elementů vlastností můžete vytvořit instanci jiného objektu a nastavit jeho vlastnosti. Vlastnost můžete například explicitně nastavit VerticalOptions
na LayoutOptions
hodnotu s nastavením vlastnosti:
<Label>
...
<Label.VerticalOptions>
<LayoutOptions Alignment="Center" />
</Label.VerticalOptions>
</Label>
Další příklad: Má Grid
dvě vlastnosti pojmenované RowDefinitions
a ColumnDefinitions
. Tyto dvě vlastnosti jsou typu RowDefinitionCollection
a ColumnDefinitionCollection
které jsou kolekcemi RowDefinition
a ColumnDefinition
objekty. K nastavení těchto kolekcí je potřeba použít syntaxi elementu vlastnosti.
Tady je začátek souboru XAML pro GridDemoPage
třídu, který zobrazuje značky elementů vlastností pro kolekce RowDefinitions
a ColumnDefinitions
kolekce:
<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>
Všimněte si zkrácené syntaxe pro definování buněk s automatickou velikostí, buněk s pixelovými šířkami a výškami a nastavením hvězdičky.
Přidružené vlastnosti
Právě jste viděli, že Grid
požadované prvky vlastností a RowDefinitions
ColumnDefinitions
kolekce definují řádky a sloupce. Pro programátora ale také musí existovat nějaký způsob, jak označit řádek a sloupec, kde se nachází každá podřízená položka Grid
.
V rámci značky pro každé podřízené položky Grid
zadáte řádek a sloupec tohoto podřízeného atributu pomocí následujících atributů:
Grid.Row
Grid.Column
Výchozí hodnoty těchto atributů jsou 0. Můžete také určit, jestli podřízená položka zahrnuje více než jeden řádek nebo sloupec s těmito atributy:
Grid.RowSpan
Grid.ColumnSpan
Tyto dva atributy mají výchozí hodnoty 1.
Tady je kompletní soubor GridDemoPage.xaml:
<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 a Grid.Column
nastavení 0 nejsou povinné, ale jsou obecně zahrnuty pro účely přehlednosti.
Vypadá takto:
Judging výhradně ze syntaxe, tyto , , a atributy se zdá být statické pole nebo vlastnosti Grid
, ale zajímavé dostatečně, Grid
nedefinuje nic pojmenovaného Row
, Column
, RowSpan
, nebo ColumnSpan
.Grid.ColumnSpan
Grid.RowSpan
Grid.Column
Grid.Row
Grid
Místo toho definuje čtyři vlastnosti s možností vytvoření vazby s názvem RowProperty
, ColumnProperty
, RowSpanProperty
a ColumnSpanProperty
. Jedná se o speciální typy vazebných vlastností označovaných jako připojené vlastnosti. Jsou definovány Grid
třídou, ale nastaveny na podřízené Grid
položky .
Pokud chcete tyto připojené vlastnosti použít v kódu, Grid
třída poskytuje statické metody s názvem SetRow
, GetColumn
a tak dále. V jazyce XAML jsou však tyto připojené vlastnosti nastaveny jako atributy v podřízených objektech pomocí jednoduchých Grid
názvů vlastností.
Připojené vlastnosti jsou vždy rozpoznatelné v souborech XAML jako atributy obsahující třídu i název vlastnosti oddělené tečkou. Nazývají se připojené vlastnosti , protože jsou definovány jednou třídou (v tomto případě Grid
), ale připojeny k jiným objektům (v tomto případě podřízené položky Grid
). Během rozložení může interrogovat hodnoty těchto připojených vlastností, abyste věděli, Grid
kam umístit jednotlivé podřízené objekty.
Třída AbsoluteLayout
definuje dvě připojené vlastnosti pojmenované LayoutBounds
a LayoutFlags
. Zde je model kontrolní desky realizované pomocí proporcionálního umístění a určení velikosti funkcí 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>
A tady je:
Pro něco takového byste mohli položit otázku moudrosti použití XAML. Jistě, opakování a správnost obdélníku LayoutBounds
naznačuje, že by mohlo být lépe realizováno v kódu.
To je jistě legitimní obava a není problém s vyvážením použití kódu a značek při definování uživatelských rozhraní. Je snadné definovat některé vizuály v JAZYCE XAML a pak pomocí konstruktoru souboru kódu přidat další vizuály, které můžou být lépe generovány ve smyčce.
Vlastnosti obsahu
V předchozích příkladech jsou objekty a objekty Grid
nastaveny na Content
vlastnost ContentPage
, a podřízené položky těchto rozložení jsou ve skutečnosti položky v kolekciChildren
.AbsoluteLayout
StackLayout
Content
Tyto vlastnosti Children
ale nejsou nikde v souboru XAML.
Určitě můžete zahrnout vlastnosti a Children
vlastnosti jako elementy Content
vlastností, například v ukázce XamlPlusCode:
<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>
Skutečnou otázkou je: Proč nejsou tyto elementy vlastností v souboru XAML povinné?
Elementy definované Xamarin.Forms pro použití v XAML mohou mít jednu vlastnost označenou v ContentProperty
atributu třídy. Pokud třídu vyhledáte ContentPage
v online Xamarin.Forms dokumentaci, uvidíte tento atribut:
[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage
To znamená, že značky elementu Content
property nejsou povinné. Předpokládá se, že se k vlastnosti přiřadí veškerý obsah XML, který se zobrazí mezi počáteční a koncovou ContentPage
značkou Content
.
StackLayout
, Grid
, AbsoluteLayout
a RelativeLayout
všechny odvozeny od Layout<View>
, a pokud hledáte Layout<T>
v Xamarin.Forms dokumentaci, uvidíte další ContentProperty
atribut:
[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout ...
To umožňuje automatické přidání obsahu rozložení do Children
kolekce bez explicitních Children
značek elementů vlastností.
Jiné třídy mají ContentProperty
také definice atributů. Například vlastnost Label
obsahu je Text
. Projděte si dokumentaci k rozhraní API pro ostatní.
Rozdíly mezi platformami s onPlatformem
V jednostrákových aplikacích je běžné nastavit Padding
vlastnost na stránce, aby se zabránilo přepsání stavového řádku iOS. V kódu můžete vlastnost použít k tomuto účelu Device.RuntimePlatform
:
if (Device.RuntimePlatform == Device.iOS)
{
Padding = new Thickness(0, 20, 0, 0);
}
V XAML můžete také provádět něco podobného OnPlatform
pomocí a On
tříd. Nejprve zahrňte elementy vlastnosti pro Padding
vlastnost v horní části stránky:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
</ContentPage.Padding>
...
</ContentPage>
Do těchto značek zahrňte značku OnPlatform
. OnPlatform
je obecná třída. V tomto případě je třeba zadat argument obecného typu, Thickness
což je typ Padding
vlastnosti. Naštěstí existuje atribut XAML speciálně pro definování obecných argumentů volaný x:TypeArguments
. Mělo by se shodovat s typem vlastnosti, kterou nastavujete:
<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
má vlastnost s názvem Platforms
, která je objekty IList
On
. Pro tuto vlastnost použijte značky elementů vlastností:
<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>
Teď přidejte On
prvky. Pro každou z nich nastavte Platform
vlastnost a Value
vlastnost na revize vlastnosti Thickness
:
<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>
Tento kód lze zjednodušit. Vlastnost obsahu OnPlatform
je Platforms
, takže tyto značky elementů vlastností lze odebrat:
<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>
Vlastnost Platform
On
je typu IList<string>
, takže můžete zahrnout více platforem, pokud jsou hodnoty stejné:
<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>
Vzhledem k tomu, že Android a UPW jsou nastaveny na výchozí hodnotu Padding
, lze tuto značku odebrat:
<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>
Toto je standardní způsob nastavení vlastnosti závislé Padding
na platformě v JAZYCE XAML. Value
Pokud nastavení nemůže být reprezentováno jedním řetězcem, můžete pro něj definovat prvky vlastností:
<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>
Poznámka:
Rozšíření OnPlatform
značek lze také použít v JAZYCE XAML k přizpůsobení vzhledu uživatelského rozhraní na základě jednotlivých platforem. Poskytuje stejné funkce jako OnPlatform
třídy a On
poskytuje stručnější reprezentaci. Další informace naleznete v tématu OnPlatform Markup Extension.
Shrnutí
U elementů vlastností a připojených vlastností byla vytvořena většina základní syntaxe XAML. Někdy ale potřebujete nastavit vlastnosti na objekty nepřímým způsobem, například ze slovníku prostředků. Tento přístup je popsaný v další části, část 3. Rozšíření značek XAML