Sdílet prostřednictvím


1. část: Začínáme s jazykem XAML

Xamarin.Forms V aplikaci se XAML většinou používá k definování vizuálního obsahu stránky a spolupracuje se souborem kódu jazyka C#.

Soubor s kódem poskytuje podporu kódu pro značky. Tyto dva soubory společně přispívají k nové definici třídy, která zahrnuje podřízená zobrazení a inicializaci vlastností. V souboru XAML se na třídy a vlastnosti odkazují elementy a atributy XML a vytvoří se propojení mezi kódem a kódem.

Vytvoření řešení

Pokud chcete začít upravovat první soubor XAML, vytvořte nové Xamarin.Forms řešení pomocí sady Visual Studio nebo Visual Studio pro Mac. (Vyberte kartu níže odpovídající vašemu prostředí.)

Ve Windows spusťte Visual Studio 2019 a v úvodním okně klikněte na Vytvořit nový projekt a vytvořte nový projekt:

Nové okno řešení

V okně Vytvořit nový projekt vyberte v rozevíracím seznamu Typ projektu mobilní aplikaci, vyberte šablonu Mobilní aplikace (Xamarin.Forms) a klikněte na tlačítko Další:

Okno Nový projekt

V okně Konfigurovat nový projekt nastavte název projektu na XamlSamples (nebo cokoli jiného) a klikněte na tlačítko Vytvořit.

V dialogovém okně Nová aplikace pro různé platformy klikněte na Prázdné a klikněte na tlačítko OK:

Dialogové okno Nová aplikace

V řešení se vytvářejí čtyři projekty: knihovna XamlSamples .NET Standard, XamlSamples.Android, XamlSamples.iOS a Univerzální platforma Windows řešení XamlSamples.UWP.

Po vytvoření řešení XamlSamples můžete chtít otestovat vývojové prostředí výběrem různých projektů platformy jako spouštěcího projektu řešení a sestavením a nasazením jednoduché aplikace vytvořené šablonou projektu na emulátorech telefonu nebo skutečných zařízeních.

Pokud nepotřebujete psát kód specifický pro platformu, sdílený projekt knihovny XamlSamples .NET Standard je místo, kde budete strávit prakticky veškerý čas programování. Tyto články se nebudou vypouštět mimo tento projekt.

Anatomie souboru XAML

V knihovně XamlSamples .NET Standard jsou dvojice souborů s následujícími názvy:

  • App.xaml, soubor XAML a
  • App.xaml.cs soubor kódu jazyka C# přidružený k souboru XAML.

Pokud chcete zobrazit soubor kódu za kódem, budete muset kliknout na šipku vedle souboru App.xaml .

App.xaml i App.xaml.cs přispívají do třídy, App která je odvozena od Application. Většina ostatních tříd se soubory XAML přispívá ke třídě, která je odvozena ; ContentPagetyto soubory používají XAML k definování vizuálního obsahu celé stránky. To platí pro ostatní dva soubory v projektu XamlSamples :

  • MainPage.xaml, soubor XAML a
  • MainPage.xaml.cs soubor kódu jazyka C#.

Soubor MainPage.xaml vypadá takto (i když formátování může být trochu jiné):

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples"
             x:Class="XamlSamples.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Welcome to Xamarin Forms!"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
    </StackLayout>

</ContentPage>

Dvě deklarace oboru názvůxmlns XML odkazují na identifikátory URI, první zdánlivě na webu Xamarinu a druhé na webu Microsoftu. Neobtěžujte kontrolu, na co tyto identifikátory URI odkazují. Není tam nic. Jsou to jednoduše identifikátory URI vlastněné Xamarinem a Microsoftem a v podstatě fungují jako identifikátory verzí.

První deklarace oboru názvů XML znamená, že značky definované v souboru XAML bez předpony odkazují na třídy, Xamarin.Formsnapříklad ContentPage. Druhá deklarace oboru názvů definuje předponu .x Používá se pro několik prvků a atributů, které jsou vnitřní pro samotný XAML a které jsou podporovány jinými implementacemi XAML. Tyto prvky a atributy se ale mírně liší v závislosti na roce vloženém do identifikátoru URI. Xamarin.Forms podporuje specifikaci XAML 2009, ale ne všechny.

Deklarace local oboru názvů umožňuje přístup k jiným třídám z projektu knihovny .NET Standard.

Na konci první značky se předpona x používá pro atribut s názvem Class. Vzhledem k tomu, že použití této x předpony je prakticky univerzální pro obor názvů XAML, atributy XAML, jako Class jsou téměř vždy označovány jako x:Class.

Atribut x:Class určuje plně kvalifikovaný název třídy .NET: MainPage třídu v XamlSamples oboru názvů. To znamená, že tento soubor XAML definuje novou třídu pojmenovanou MainPage v XamlSamples oboru názvů, která je odvozena od ContentPageznačky, ve které x:Class se atribut zobrazí.

Atribut x:Class se může objevit pouze v kořenovém prvku souboru XAML pro definování odvozené třídy jazyka C#. Toto je jediná nová třída definovaná v souboru XAML. Všechno ostatní, co se zobrazí v souboru XAML, se místo toho jednoduše vytvoří instance z existujících tříd a inicializuje se.

Soubor MainPage.xaml.cs vypadá takto (kromě nepoužívaných using direktiv):

using Xamarin.Forms;

namespace XamlSamples
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
}

Třída MainPage je odvozena od ContentPage, ale všimněte si partial definice třídy. To naznačuje, že by měla existovat další částečná definice třídy , MainPageale kde je? A co je to InitializeComponent metoda?

Když Visual Studio projekt sestaví, parsuje soubor XAML a vygeneruje soubor kódu jazyka C#. Pokud se podíváte do adresáře XamlSamples\XamlSamples\obj\Debug , najdete soubor s názvem XamlSamples.MainPage.xaml.g.cs. "g" je zkratka pro vygenerované. Toto je druhá částečná definice MainPage třídy, která obsahuje definici InitializeComponent metody volané z konstruktoru MainPage . Tyto dvě částečné MainPage definice tříd je pak možné zkompilovat společně. V závislosti na tom, jestli je XAML kompilovaný nebo ne, je soubor XAML nebo binární forma souboru XAML vložena do spustitelného souboru.

Za běhu kód v konkrétním projektu platformy volá metodu LoadApplication , která jí předává novou instanci App třídy v knihovně .NET Standard. Vytvoří App instanci konstruktoru MainPagetřídy . Konstruktor této třídy volá InitializeComponent, který pak volá metodu LoadFromXaml , která extrahuje soubor XAML (nebo jeho kompilovaný binární soubor) z knihovny .NET Standard. LoadFromXaml inicializuje všechny objekty definované v souboru XAML, propojí je všechny v relacích nadřazených a podřízených, připojí obslužné rutiny událostí definované v kódu k událostem nastaveným v souboru XAML a nastaví výsledný strom objektů jako obsah stránky.

I když obvykle nemusíte trávit mnoho času s vygenerovanými soubory kódu, někdy jsou výjimky modulu runtime vyvolány v kódu v vygenerovaných souborech, takže byste se s nimi měli seznámit.

Při kompilaci a spuštění tohoto programu Label se prvek zobrazí uprostřed stránky, jak navrhuje XAML:

Výchozí Xamarin.Forms zobrazení

Pro zajímavější vizuály je vše, co potřebujete, zajímavější XAML.

Přidání nových stránek XAML

Pokud chcete do projektu přidat další třídy založené na ContentPage XAML, vyberte projekt knihovny XamlSamples .NET Standard, klikněte pravým tlačítkem myši a vyberte Přidat > novou položku.... V dialogovém okně Přidat novou položku vyberte stránku obsahu položekXamarin.Forms>> v jazyce Visual C# (ne stránka obsahu (C#), která vytvoří stránku určenou jen pro kód nebo zobrazení obsahu, což není stránka). Pojmenujte stránku, například HelloXamlPage:

Dialogové okno Přidat novou položku

Do projektu se přidají dva soubory HelloXamlPage.xaml a HelloXamlPage.xaml.cs souboru kódu.

Nastavení obsahu stránky

Upravte soubor HelloXamlPage.xaml tak, aby byly pouze značky pro ContentPage aContentPage.Content:

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

    </ContentPage.Content>
</ContentPage>

Značky ContentPage.Content jsou součástí jedinečné syntaxe XAML. Zpočátku se může zdát, že jsou neplatné XML, ale jsou legální. Tečka není ve formátu XML speciální znak.

Značky ContentPage.Content se nazývají značky elementu vlastnosti. Content je vlastnost ContentPagea je obecně nastavena na jedno zobrazení nebo rozložení s podřízenými zobrazeními. Obvykle se vlastnosti stanou atributy v XAML, ale bylo by obtížné nastavit Content atribut na komplexní objekt. Z tohoto důvodu je vlastnost vyjádřena jako element XML sestávající z názvu třídy a název vlastnosti oddělené tečkou. Content Teď můžete vlastnost nastavit mezi ContentPage.Content značkami, například takto:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.HelloXamlPage"
             Title="Hello XAML Page">
    <ContentPage.Content>

        <Label Text="Hello, XAML!"
               VerticalOptions="Center"
               HorizontalTextAlignment="Center"
               Rotation="-15"
               IsVisible="true"
               FontSize="Large"
               FontAttributes="Bold"
               TextColor="Blue" />

    </ContentPage.Content>
</ContentPage>

Všimněte si také, že Title atribut byl nastaven na kořenové značce.

V tuto chvíli by měl být vztah mezi třídami, vlastnostmi a XML zřejmé: Xamarin.Forms Třída (například ContentPage nebo Label) se v souboru XAML zobrazí jako element XML. Vlastnosti této třídy ( včetně Title vlastností a ContentPage sedmi vlastností Label) se obvykle zobrazují jako atributy XML.

Existuje mnoho zástupců pro nastavení hodnot těchto vlastností. Některé vlastnosti jsou základní datové typy: Například Title a Text vlastnosti jsou typu String, Rotation jsou typu Double, a IsVisible (který je true ve výchozím nastavení a je zde nastaven pouze pro ilustraci) je typu Boolean.

Vlastnost HorizontalTextAlignment je typu TextAlignment, což je výčet. Pro vlastnost libovolného typu výčtu je vše, co je třeba zadat, je název člena.

Pro vlastnosti složitějších typů se však převaděče používají k analýze XAML. Jedná se o třídy, Xamarin.Forms které jsou odvozeny z TypeConverter. Mnoho z nich jsou veřejné třídy, ale některé nejsou. Pro tento konkrétní soubor XAML hraje několik z těchto tříd roli na pozadí:

  • LayoutOptionsConverterVerticalOptions pro vlastnost
  • FontSizeConverterFontSize pro vlastnost
  • ColorTypeConverterTextColor pro vlastnost

Tyto převaděče řídí povolenou syntaxi nastavení vlastnosti.

Dokáže ThicknessTypeConverter zpracovat jedno, dvě nebo čtyři čísla oddělená čárkami. Pokud je zadáno jedno číslo, platí pro všechny čtyři strany. Se dvěma čísly je první levý a pravý odsazení a druhý je nahoře a dole. Čtyři čísla jsou v levém pořadí, nahoře, vpravo a dole.

Názvy LayoutOptionsConverter veřejných statických LayoutOptions polí struktury lze převést na hodnoty typu LayoutOptions.

Člen FontSizeConverter nebo velikost číselného písma může zpracovat NamedSize .

Přijímá ColorTypeConverter názvy veřejných statických polí Color struktury nebo šestnáctkových hodnot RGB s alfa kanálem a před znakem čísla (#). Tady je syntaxe bez alfa kanálu:

TextColor="#rrggbb"

Každá malá písmena je šestnáctková číslice. Tady je postup zahrnutí alfa kanálu:

TextColor="#aarrggbb">

Pro alfa kanál mějte na paměti, že FF je plně neprůhledný a 00 je plně transparentní.

Dva další formáty umožňují zadat pouze jednu šestnáctkovou číslici pro každý kanál:

TextColor="#rgb" TextColor="#argb"

V těchto případech se číslice opakuje, aby se vytvořila hodnota. Například #CF3 je barva RGB CC-FF-33.

Když spustíte program XamlSamples , zobrazí se MainPage . Pokud chcete zobrazit novou HelloXamlPage , můžete ji nastavit jako novou spouštěcí stránku v souboru App.xaml.cs nebo přejít na novou stránku z MainPage.

Pokud chcete implementovat navigaci, nejprve změňte kód v konstruktoru App.xaml.cs tak, aby NavigationPage byl vytvořen objekt:

public App()
{
    InitializeComponent();
    MainPage = new NavigationPage(new MainPage());
}

V konstruktoru MainPage.xaml.cs můžete vytvořit jednoduchou Button obslužnou rutinu události a přejít na HelloXamlPage:

public MainPage()
{
    InitializeComponent();

    Button button = new Button
    {
        Text = "Navigate!",
        HorizontalOptions = LayoutOptions.Center,
        VerticalOptions = LayoutOptions.Center
    };

    button.Clicked += async (sender, args) =>
    {
        await Navigation.PushAsync(new HelloXamlPage());
    };

    Content = button;
}

Content Nastavení vlastnosti stránky nahrazuje nastavení Content vlastnosti v souboru XAML. Když zkompilujete a nasadíte novou verzi tohoto programu, zobrazí se na obrazovce tlačítko. Stisknutím klávesy přejdete na HelloXamlPage. Tady je výsledná stránka na i Telefon, Androidu a UPW:

Otočený text popisku

Zpět můžete přejít MainPage pomocí < tlačítka Zpět v iOSu, pomocí šipky vlevo v horní části stránky nebo v dolní části telefonu v Androidu nebo pomocí šipky vlevo v horní části stránky ve Windows 10.

Nebojte se experimentovat s XAML pro různé způsoby vykreslení Label. Pokud potřebujete do textu vložit jakékoli znaky Unicode, můžete použít standardní syntaxi XML. Pokud například chcete pozdrav vložit do inteligentních uvozovek, použijte:

<Label Text="&#x201C;Hello, XAML!&#x201D;" … />

Vypadá takto:

Otočený text popisku se znaky Unicode

Interakce XAML a kódu

Ukázka HelloXamlPage obsahuje jenom jeden Label na stránce, ale to je velmi neobvyklé. Většina ContentPage derivátů nastaví Content vlastnost na rozložení určitého druhu, například StackLayout. Vlastnost Children objektu StackLayout je definována tak, aby byla typu, IList<View> ale ve skutečnosti se jedná o objekt typu ElementCollection<View>a že kolekci lze naplnit více zobrazeními nebo jinými rozloženími. V jazyce XAML jsou tyto relace nadřazeného a podřízeného objektu vytvořeny s normální hierarchií XML. Tady je soubor XAML pro novou stránku s názvem XamlPlusCodePage:

<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">
    <StackLayout>
        <Slider VerticalOptions="CenterAndExpand" />

        <Label Text="A simple Label"
               Font="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Button Text="Click Me!"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Tento soubor XAML je syntakticky úplný a vypadá takto:

Více ovládacích prvků na stránce

Pravděpodobně ale tento program považujete za funkčně nedosažitý. Možná Slider by to mělo způsobit Label zobrazení aktuální hodnoty a Button pravděpodobně má udělat něco v programu.

Jak uvidíte v části 4. Základní informace o datových vazbách, úloha zobrazení Slider hodnoty pomocí jazyka Label XAML s datovou vazbou. Je ale užitečné vidět řešení kódu jako první. I tak zpracování Button kliknutí rozhodně vyžaduje kód. To znamená, že soubor kódu za XamlPlusCodePage kódem musí obsahovat obslužné rutiny pro ValueChanged událost Slider události a Clicked události události Button. Pojďme je přidat:

namespace XamlSamples
{
    public partial class XamlPlusCodePage
    {
        public XamlPlusCodePage()
        {
            InitializeComponent();
        }

        void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
        {

        }

        void OnButtonClicked(object sender, EventArgs args)
        {

        }
    }
}

Tyto obslužné rutiny událostí nemusí být veřejné.

Zpět v souboru Slider XAML musí značky Button obsahovat atributy pro ValueChanged události a Clicked události, které odkazují na tyto obslužné rutiny:

<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">
    <StackLayout>
        <Slider VerticalOptions="CenterAndExpand"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="A simple Label"
               Font="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

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

Všimněte si, že přiřazení obslužné rutiny události má stejnou syntaxi jako přiřazení hodnoty k vlastnosti.

Pokud obslužná rutina události ValueChangedSlider bude používat Label k zobrazení aktuální hodnoty, obslužná rutina musí odkazovat na tento objekt z kódu. Potřebuje Label název, který je zadaný atributem x:Name .

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

x Předpona atributu x:Name označuje, že tento atribut je vnitřní pro XAML.

Název, který přiřadíte k atributu x:Name , má stejná pravidla jako názvy proměnných jazyka C#. Musí například začínat písmenem nebo podtržítkem a obsahovat žádné vložené mezery.

Obslužná rutina ValueChanged události teď může nastavit Label zobrazení nové Slider hodnoty. Nová hodnota je k dispozici z argumentů události:

void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
    valueLabel.Text = args.NewValue.ToString("F3");
}

Nebo obslužná rutina může získat Slider objekt, který generuje tuto událost z argumentu sender a získat Value vlastnost z této:

void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
    valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}

Při prvním spuštění programu se hodnota nezobrazíSlider, Label protože ValueChanged událost se ještě neaktivovala. Ale jakákoli manipulace s příčinami, že Slider se hodnota zobrazí:

Zobrazená hodnota posuvníku

Nyní pro Button. Pojďme simulovat odpověď na Clicked událost zobrazením výstrahy s Text tlačítkem. Obslužná rutina události může bezpečně přetypovat sender argument na Button objekt a pak přistupovat k jeho vlastnostem:

async void OnButtonClicked(object sender, EventArgs args)
{
    Button button = (Button)sender;
    await DisplayAlert("Clicked!",
        "The button labeled '" + button.Text + "' has been clicked",
        "OK");
}

Metoda je definována tak, async že DisplayAlert metoda je asynchronní a měla by být před operátorem await , který vrátí po dokončení metody. Vzhledem k tomu, že tato metoda získá aktivaci Button události z argumentu sender , lze stejnou obslužnou rutinu použít pro více tlačítek.

Viděli jste, že objekt definovaný v XAML může aktivovat událost, která je zpracována v souboru kódu za kódem a že soubor kódu za ním může přistupovat k objektu definovanému v XAML pomocí názvu přiřazeného atributem x:Name . Toto jsou dva základní způsoby interakce kódu a XAML.

Několik dalších přehledů o tom, jak XAML funguje, můžete prozkoumat nově vygenerovaný soubor XamlPlusCode.xaml.g.cs, který teď obsahuje libovolný název přiřazený k libovolnému x:Name atributu jako soukromé pole. Tady je zjednodušená verze tohoto souboru:

public partial class XamlPlusCodePage : ContentPage {

    private Label valueLabel;

    private void InitializeComponent() {
        this.LoadFromXaml(typeof(XamlPlusCodePage));
        valueLabel = this.FindByName<Label>("valueLabel");
    }
}

Deklarace tohoto pole umožňuje volně používat proměnnou kdekoli v rámci souboru částečné třídy ve XamlPlusCodePage vaší jurisdikci. Za běhu se pole přiřadí po parsování XAML. To znamená, že valueLabel pole je null , když XamlPlusCodePage konstruktor začíná, ale je platný po InitializeComponent zavolání.

Po InitializeComponent návratu ovládacího prvku zpět do konstruktoru byly vizuály stránky sestaveny stejně, jako kdyby byly vytvořené a inicializovány v kódu. Soubor XAML už ve třídě nepřehrává žádnou roli. Tyto objekty na stránce můžete manipulovat libovolným způsobem, například přidáním zobrazení do objektu StackLayoutnebo nastavením Content vlastnosti stránky na něco jiného. Strom můžete "procházet" prozkoumáním Content vlastnosti stránky a položek v Children kolekcích rozložení. Vlastnosti zobrazení, ke kterým se přistupuje tímto způsobem, můžete nastavit nebo jim dynamicky přiřadit obslužné rutiny událostí.

Nebojte se. Je to vaše stránka a XAML je jen nástroj pro sestavení jeho obsahu.

Shrnutí

V tomto úvodu jste viděli, jak soubor XAML a soubor kódu přispívají k definici třídy a jak soubory XAML a kódu komunikují. XAML má ale také své vlastní syntaktické funkce, které umožňují jeho použití velmi flexibilním způsobem. Můžete je začít zkoumat v části 2. Základní syntaxe XAML