Lekce 2 - Jazyk XAML ve WinUI 3 a C# .NET
V minulé lekci, Úvod do Windows App SDK a WinUI 3, jsme si představili technologie Windows App SDK a WinUI 3. Naprogramovali jsme si také svou první jednoduchou desktopovou aplikaci v C# .NET.
V dnešním WinUI 3 tutoriálu si popíšeme základy jazyka XAML, který se používá k návrhu komponent aplikace. Zmíníme elementy, jmenné prostory a entity.
XAML
Již víme, že jazyk XAML slouží ke kódování prezentační vrstvy komponent aplikace. Laicky řečeno v jazyce XAML zapisujeme, jak má okno aplikace vypadat. XAML vychází z XML, což je značkovací jazyk navržený tak, aby si do něj každý mohl přidat své vlastní značky a mohl ho používat úplně k čemukoli. XML je velmi rozšířené a mnoho z vás ho jistě zná například jako XHTML, což je jeho podoba se značkami pro tvorbu webových stránek. Kdo umí HTML, má velkou výhodu, i když narazíme na pár odlišností od XML.
Zkratka XML odkazuje na slova eXtensible Markup Language, tedy rozšiřitelný značkovací jazyk. XAML je potom zkratkou pro eXtensible Application Markup Language, tedy jednoduše řečeno XML se značkami pro tvorbu aplikací.
Základní charakteristiky
XAML jsme již měli možnost vidět při tvorbě našeho prvního
příkladu. XAML kód pro okno s jedním textovým popiskem
TextBlock
vypadá následovně:
<?xml version="1.0" encoding="utf-8"?> <Window x:Class="HelloWinUI.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HelloWinUI" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock>Pozdrav z WinUI 3 aplikace</TextBlock> </StackPanel> </Window>
Na tomto jednoduchém příkladu si vysvětlíme základní charakteristiky jazyka XML, a tedy i XAML.
Stromová struktura
XML dokument se skládá z elementů. Struktura dokumentu je stromová. To znamená, že elementy v sobě mohou obsahovat libovolné množství dalších elementů, ty zase další elementy a tak dále. Každý XML dokument však obsahuje právě jeden kořenový element, v němž jsou dále umístěny další podelementy. Vkládání elementů do sebe se říká nesting, což by se dalo přeložit jako hnízdění.
Dokument výše obsahuje kořenový element <Window>
(okno), v něm je dále vložený element <StackPanel>
(chápejme jej jako panel na ovládací prvky) a v tomto panelu je vložený
element <TextBlock>
, což je nám již známý textový
popisek.
XML, a tedy i XAML dokument dále obsahují i hlavičku, která určuje například použité kódování textu. Hlavička našeho dokumentu vypadá takto:
<?xml version="1.0" encoding="utf-8"?>
Elementy
Elementy (někdy také tagy = značky) zapisujeme do lomených závorek, ve kterých je vždy název elementu. Každý element je v XML nutné ukončit (to je rozdíl oproti HTML, kde je ukončení nepovinné). Elementy ukončujeme podle toho, zda jsou párové, nebo nepárové. Nepárové elementy zapíšeme takto:
<TextBlock />
K ukončení nepárového elementu použijeme lomítko před zavírací lomenou závorkou.
Párové elementy ukončíme umístěním další značky s názvem elementu,
kde je po levé lomené závorce lomítko. Dovnitř párových elementů se
vkládá obsah nebo další elementy. Obsah elementem vlastně označíme a
přidělíme mu nějaký význam, od toho zkratka XML. Níže označujeme text
Pozdrav z WinUI 3 aplikace
a říkáme, že se jedná
o obsah textového bloku TextBlock
:
<TextBlock>Pozdrav z WinUI 3 aplikace</TextBlock>
Obsah můžeme stejně tak vložit i do atributu. Ty se zapisují stejně u párových i nepárových elementů, a to do uvozovek za název atributu a rovnítko:
<TextBlock Text="Pozdrav z WinUI 3 aplikace" />
Vidíme, že element <TextBlock>
můžeme zapsat jako
párový i nepárový a jeho obsah vložit buď pomocí atributu, nebo jako
obsah elementu. Jaké jsou názvy elementů, jejich párovost a atributy,
samozřejmě určuje specifikace konkrétního jazyka, zde jazyka XAML.
Názvy elementů vždy odpovídají názvům C# tříd, kterými
jsou odpovídající komponenty tvořeny. Například textový popisek
TextBlock
je tvořen C# třídou TextBlock
. V XAML
kódu jej tak reprezentujeme elementem <TextBlock>
.
Atributů může mít každý element libovolné množství, jedná se ve skutečnosti o vlastnosti C# třídy, kterou daný element reprezentuje. Do atributů nelze vložit další element, pouze textovou hodnotu.
Jmenné prostory
Z kurzu Objektově orientované programování v C# .NET víme, že v C# existují tzv. jmenné prostory. Jedná se o balíčky, které v sobě obsahují jednotlivé třídy nebo další balíčky. Byly zavedeny z toho důvodu, že v .NET je opravdu obrovské množství tříd. Bez jmenných prostorů by musela mít každá třída unikátní název a také bychom nemohli vytvořit svou vlastní třídu, která se jmenuje stejně jako nějaká třída z .NET. Tomuto problému se říká kolize názvů.
Pokud používáme jmenné prostory, uvedeme na začátku dokumentu, které komponenty z kterých jmenných prostorů budeme používat. Můžeme tak mít několik komponent se stejným názvem. To ničemu nevadí, používáme-li v jeden čas jen jednu komponentu z jednoho jmenného prostoru. Pomocí tzv. aliasů můžeme komponentu pro daný dokument dospecifikovat, a používat tak více komponent se stejným názvem v jednu chvíli pod jiným označením.
V odstavci výše jsme mluvili obecně o komponentách. Jmenné prostory v C#
.NET obsahují zejména třídy, v XML pak elementy. Jmennými prostory tedy
říkáme, které "balíčky se značkami" budeme v dokumentu potřebovat.
Často se uvádí příklad XML dokumentu, kde je element
<table>
jednou ze jmenného prostoru web
, kde
označuje tabulku, a jednou ze jmenného prostoru shop
, kde
označuje stůl.
Jmenné prostory v XAML
Jmenné prostory, s nimiž chceme pracovat, se v XAML nastavují v
kořenovém elementu, v našem případě tedy ve <Window>
, a
to pomocí atributu xmlns
(jako XML
Name Space). Visual Studio nám ve
vygenerovaném kódu připravilo k použití několik "balíčků značek"
(mohou se lišit dle verze WinUI 3):
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HelloWinUI" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Přestože jsou jmenné prostory označovány pomocí URL, nejedná se o
skutečnou webovou adresu, nýbrž pouze o název. První jmenný prostor
obsahuje základní elementy pro tvorbu WinUI 3 aplikací. Jde o výchozí
jmenný prostor. Jakmile napíšeme nějakou značku, bude se automaticky brát
právě z tohoto prostoru (např. element <Window>
nebo
<TextBlock>
).
Druhý jmenný prostor má již přidělený alias x
, a pokud
budeme chtít používat značky z něj, musíme před jejich název vložit
x:
. V tomto jmenném prostoru jsou obsažené definice
rozšiřujících parametrů. V příkladu kódu výše vidíme, že element
<Window>
má atribut x:Class
. Ten určuje název
třídy s C# kódem, který okno obsluhuje (tedy code behind).
Na jmenném prostoru s přiřazeným aliasem local
můžeme
vidět, jak lze připojit nějaký jmenný prostor z našeho projektu.
Konkrétně se zde připojuje kořenový jmenný prostor
HelloWinUI
, ve kterém se například nachází třída okna
MainWindow
. Před označením požadovaného jmenného prostoru v
atributu je potřeba uvést ještě předponu using:
. Označení
jmenného prostoru je pak stejné, jako jsme zvyklí ze C#. Připojení
vlastního jmenného prostoru se hodí především pro vkládání vlastních
komponent.
Entity
Možná vás napadlo, co se stane, když do obsahu elementu nebo atributu
vložíme lomenou závorku, uvozovku nebo jiný znak, který se v syntaxi XML
používá. Dokument přestane být validní, a někdy to dokonce může
zapříčinit i chybu při běhu aplikace. Proto byly zavedeny tzv. entity, což
jsou náhrady zejména za znaky <
, >
,
&
, "
.
Entity zapisujeme tímto způsobem:
<
– Less Than (menší než),>
– Greater Than (větší než),&
– ampersand (&
),"
– uvozovka ("
).
Text 5 > 6
by tedy v bloku TextBlock
vypadal
takto:
<TextBlock>5 > 6</TextBlock>
V příští lekci, Pozicování ve WinUI 3 a C# .NET, se naučíme pozicovat ovládací prvky v okně. Zmíníme layouty, absolutní a relativní pozici, DIP, vnější a vnitřní okraje a velikost.