Lekce 3 - Pozicování v C# .NET WPF
V minulé lekci, Jazyk XAML v C# .NET WPF, jsme si uvedli základní syntaxi jazyka XAML.
V dnešním WPF tutoriálu se naučíme elementy pozicovat.
Absolutní a relativní pozice
Dříve jsme již zmínili, že WPF zavádí relativní pozici prvků na
formuláři. V naší první aplikaci s pozdravem měl však
TextBlock
pozici absolutní. Pojďme se podívat na jeho XAML kód,
který vygeneroval grafický návrhář ve chvíli, co jsme
TextBlock
na formulář přidali z ToolBoxu:
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="100,35,0,0" TextWrapping="Wrap" Text="Pozdrav z formuláře" VerticalAlignment="Top"/>
Absolutní pozice
Ve WPF přímo do elementu Grid
v okně nelze vkládat prvky na
absolutní pozici, můžeme si však pomoci okrajem. Návrhář v příkladu
výše zjistil, že jsme ovládací prvek vložili na souřadnice
[100;35]
. Aby jej tam zobrazil, umístí jej vlevo nahoru (proto
atributy HorizontalAlignment="Left"
a
VerticalAlignment="Top"
) a nastaví mu vnější okraje na
100
zleva a 35
shora atributem Margin
.
Tak to vypadá, že je ovládací prvek na pozici [100;35]
, ale ve
skutečnosti je kolem něj okraj.
Asi největší nevýhoda používání absolutních pozic je, že formulář nereaguje na roztažení nebo dokonce změnu poměru jeho stran. To se dnešním aplikacím často stává, jelikož každé zařízení má jinak velký displej (mobil, tablet, PC). Další nevýhodou je, že pokud nějaký ovládací prvek zvětší svou velikost, musíme ručně ty okolní posunout, aby se formulář nerozsypal. To může být u větších aplikací opravdu velmi nepřehledné.
Ačkoli jsme TextBlock
naklikli doprostřed formuláře, po jeho
roztažení vypadá aplikace takto:
Je vidět, že naklikat prvky na pevné pozice je sice jednoduché a rychlé, ale také krátkozraké. Proto se tak formuláře již nedělají.
Relativní pozice
Relativní pozice na rozdíl od absolutní respektuje okolní prvky ve
formuláři i samotné okno. Upravme XAML kód elementu
<TextBlock>
tak, aby se centroval do elementu, ve kterém je
vložený. V našem případě bude ve středu elementu
<Grid>
:
<TextBlock x:Name="textBlock" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" Text="Pozdrav z formuláře" />
Když aplikaci nyní spustíme a formulář například zúžíme svisle a
roztáhneme vodorovně, TextBlock
je stále uprostřed. Asi
nemusím říkat, že HorizontalAlignment
nastavuje vodorovné
zarovnání a VerticalAlignment
svislé.
Okraje
Každý element má vnitřní a vnější
okraje. Vnitřním se říká Padding
a těm vnějším
Margin
:
Každý okraj můžeme nastavit jiný pro různé strany nebo ho na všech stranách elementu nastavit na jednu velikost.
Vymažeme z aplikace TextBlock
a místo něj vložíme
tlačítko pomocí následujícího XAML kódu:
<Button Content="Tlačítko" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Margin="100,0,0,0" Padding="0,50,0,0"/>
Výsledek vypadá takto:
Je vidět, že ačkoli je tlačítko zarovnané doprostřed, jeho vnější
okraj je na levé straně 100
. Tuto hodnotu jsme nastavili pomocí
Margin
. U vnitřního okraje tlačítka naopak vidíme, že ten
horní je výrazně větší než ostatní. To je hodnota 50
v
Padding
.
Hodnoty zadáváme v pořadí: levý okraj, horní, pravý, dolní a oddělujeme je čárkami. Je možné zadat jen jednu hodnotu, která nastaví všechny okraje na stejnou velikost. Stejně tak můžeme zadat i 2 hodnoty, jednu pro vodorovné okraje a jednu pro svislé.
Všimněme si, že jsme tlačítku v příkladu výše zadali
šířku pomocí atributu Width
. To se u tlačítek obvykle dělá,
jelikož nevypadá hezky, když je každé jinak široké podle délky textu v
něm.
Device Independent Pixels
Velikosti zadáváme v jednotkách DIP. DIP označuje Device
Independent Pixels. Při DPI 96
,
což je výchozí hodnota po instalaci Windows, má 1 DIP
velikost
1
fyzického pixelu na displeji. Uživatelé velkých monitorů
mají nastavené vyšší DPI (Dots Per
Inch, bodů na palec) a tedy 1
DIP vychází
např. na 1.25
fyzického pixelu. DPI bude stále důležitější,
jelikož se dají běžně koupit i 4k displeje, které mají 4x větší
rozlišení než ty, které jsou nyní standardem. Pokud by se místo DIP
používaly obyčejné pixely, naše aplikace by nebyla na takovém displeji
pomalu ani vidět. S DIP bude vypadat stále stejně, WPF tedy uzpůsobí vše
za nás.
Pozicování
Na konec dnešní lekce si zmiňme ještě něco málo o pozicování ovládacích prvků. Upravme XAML kód tlačítka tak, aby vypadal následovně:
<Button Content="Tlačítko" />
Tlačítko se roztáhne po celém gridu:
Toto je výchozí chování prvků. Pokud totiž neurčíme zarovnání,
předpokládají se v nich hodnoty Stretch
:
<Button Content="Tlačítko" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
Do atributů HorizontalAlignment
můžeme nastavit
následující hodnoty:
Center
- Zarovnání na střed.Left
- Zarovnání vlevo.Right
- Zarovnání vpravo.Stretch
- Roztažení přes celou šířku.
U VerticalAlignment
jsou hodnoty obdobné, jen
místo Left
a Right
nastavujeme Top
a
Bottom
.
Vyzkoušejme si jednotlivé hodnoty. Ovládací prvky se zarovnávají do elementu, ve kterém jsou vložené. Tomuto elementu se říká rodičovský (anglicky parent).
Výška a šířka elementů
Pro výšku a šířku elementů používáme atributy Width
a
Height
. Kromě DIP zde můžeme nastavit i hodnotu
Auto
, která je výchozí. Velikost se potom určí podle obsahu
elementu, např. podle délky textu popisku tlačítka. Můžeme také nastavit
minimální nebo maximální rozměr pomocí atributů MinWidth
,
MinHeight
, MaxWidth
a MaxHeight
.
V příští lekci, Návrh formuláře pro kalkulačku v C# .NET WPF, navrhneme formulář pro kalkulačku v C# .NET
WPF. Naučíme se přidávat sloupce a řádky do Gridu a představíme si prvky
TextBox
a ComboBox
.