Použití elementů Canvas, StackPanel a WrapPanel je ještě jednodušší, než Grid, probíraný předchozím dílu. V následujících odstavcích proberu jejich chování a možnosti nastavení. Nejčastějším způsobům použití těchto elementů dohromady budu věnovat samostatný článek.
Canvas
Canvas je elementární prvek určený k pozicování podle absolutních souřadnic. Je tedy vhodný v případech, kdy chceme mít layout pozicovaný absolutně. K určení absolutní pozice vnořených elementů se používají (podobně jako u Gridu) attached properties Canvas.JménoVlastnosti.
Pozicováni proti levému hornímu rohu lze realizovat pomocí vlastností Canvas.Top a Canvas.Left. Kód ukazuje rozmístění tlačítek do absolutních pozic proti levému hornímu okraji:
<Canvas>
<Button Canvas.Top="10" Canvas.Left="10" Content="Button 1" />
<Button Canvas.Top="40" Canvas.Left="20" Content="Button 2" />
<Button Canvas.Top="25" Canvas.Left="40" Content="Button 3" />
</Canvas>
Pokud chcete, lze se odkazovat místo vzdáleností od levého okraje vzdáleností od okraje pravého pomocí Canvas.Right místo Canvas.Left. A stejně tak vzdáleností od spodního pomocí Canvas.Bottom místo Canvas.Top. Následující kód ukazuje možné kombinace vlastností.
<Canvas>
<Button Canvas.Top="10" Canvas.Left="10" Content="Top 10, Left 10" />
<Button Canvas.Top="10" Canvas.Right="10" Content="Top 10, Right 10" />
<Button Canvas.Bottom="10" Canvas.Left="10" Content="Bottom 10, Left 10" />
<Button Canvas.Bottom="10" Canvas.Right="10" Content="Bottom 10, Right 10" />
</Canvas>
Ačkoliv záleží na typu aplikace, v běžných formulářových aplikacích většinou Canvas nevyužijete příliš často. Výjimkou může být například vytváření layoutu nad pevným grafickým návrhem, kde musí mít vše předem určenou pozici a velikost. Většinou nám ale bude bohatě stačit dynamické pozicování pomocí Gridu, StackPanelu a WrapPanelu.
StackPanel
Funkce elementu StackPanel je velmi jednoduchá, ale zároveň velmi důležité. Má za úkol řadit komponenty horizontálně vedle sebe nebo vertikálně nad sebe podle jejich velikosti. O orientaci rozhoduje vlastnost Orientation, kterou nastavujeme přímo StackPanelu. Příklad ukazuje obě varianty rozdělené do dvou sloupců v Gridu (více o Gridu).
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- horizontální StackPanel -->
<StackPanel Grid.Column="0" Orientation="Horizontal">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
</StackPanel>
<!-- vertikální StackPanel -->
<StackPanel Grid.Column="1" Orientation="Vertical">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
</StackPanel>
</Grid>
Pozicování uvnitř StackPanel
Podle předchozího příkladu je patrné, že při horizontálním uspořádání (levá polovina) se prvky na šířku skládají podle své automatické šířky a na výšku platí jejich defaultní nastavení – roztažení na celý obsah rodiče, tedy VerticalAlignment=”Stretch” (více o základech pozicování). Pokud chcete, aby si prvky na výšku vzali jen to, co potřebují, stačí jim nastavit hodnotu VerticalAlignment na Top, Bottom nebo Center. Na výběr máte nastavení buď konkrétním prvkům uvnitř StackPanelu nebo jednoduše nastavíte tuto vlastnost StackPanelu samotnému, jak ukazuje následující příklad. Úplně stejné je to v případě vertikálního uspořádání, kde můžete změnit HorizontalAlignment a tím i způsob chování šířky.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- horizontální StackPanel -->
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
</StackPanel>
<!-- vertikální StackPanel -->
<StackPanel Grid.Column="1" Orientation="Vertical" HorizontalAlignment="Center">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
</StackPanel>
</Grid>
Volba mezi StackPanelem a Gridem a jejich kombinací
Funkci StackPanelu lze teoreticky suplovat i komponentou Grid. Stačí přidat potřebné množství řádků s automatickou výškou pro vertikální řazení a do těchto řádků vkládat komponenty. Stejně tak můžete postupovat u horizontálního řazení se sloupci. Toho se často využívá v případech, kdy chceme využít i zbývající volné místo.
Následující příklad ukazuje, jak použít Grid podobným způsobem jako StackPanel, navíc s možností využití zbývajícího místa:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Content="Button 1" Grid.Row="0" />
<Button Content="Button 2" Grid.Row="1" />
<Button Content="Button 3" Grid.Row="2" />
<Label Content="Volné místo" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Content="Spodní stavový řádek" Grid.Row="4" Background="LightGray" />
</Grid>
Uvedený kód může být matoucí v případě většího množství řádků. My proto můžeme tři horní tlačítka vložit do samostatného StackPanelu a ten vložit jako jedinný řádek. Výsledek je zcela identický jako předchozí použití:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Row="0">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
</StackPanel>
<Label Content="Volné místo" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Content="Spodní stavový řádek" Grid.Row="2" Background="LightGray" />
</Grid>
Je tedy patrné, že pozicovací komponenty lze bez problémů kombinovat a vnořovat.
WrapPanel
WrapPanel je na první pohled podobný StackPanelu. Také řadí ovládací prvky do řady vedle sebe nebo pod sebe. Orientaci nastavujeme také stejně pomocí vlastnosti Orientation. Rozdíl je v chování při dosažení okraje prvku. Elementy se budou v tomto případě zalamovat na další řádky v horizontální orientaci, popřípadě na další sloupce ve vertikální orientaci. Zarovnání několika tlačítek se zalamováním demonstruje následující kód:
<WrapPanel Orientation="Horizontal">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
<Button Content="Button 5" />
<Button Content="Button 6" />
<Button Content="Button 7" />
<Button Content="Button 8" />
<Button Content="Button 9" />
<Button Content="Button 10" />
<Button Content="Button 11" />
<Button Content="Button 12" />
</WrapPanel>
Při změně velikosti formuláře se mění i rozložení WrapPanelu a přesahující prvky se zalamují na další řádky:
Kombinace s komponentou Grid
Stejně jako StackPanel i komponenta WrapPanel má řadu výhod při kombinaci s Gridem. Uvedený kód demonstruje, jak připravit rozložení s horním pruhem zalamovaných tlačítek a spodním stavovým řádkem. Opět využíváme i zbylé místo uprostřed na textový popisek centrovaný na střed.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<WrapPanel Orientation="Horizontal" Grid.Row="0" Background="LightGray">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
<Button Content="Button 5" />
<Button Content="Button 6" />
<Button Content="Button 7" />
<Button Content="Button 8" />
<Button Content="Button 9" />
<Button Content="Button 10" />
<Button Content="Button 11" />
<Button Content="Button 12" />
</WrapPanel>
<Label Content="Volné místo" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Content="Spodní stavový řádek" Grid.Row="2" Background="LightGray" />
</Grid>
Závěr
V tomto článku předvedené komponenty jsou společně s komponentou Grid základními kameny pro pozicování ve Windows Presentation Foundation. Většina pozicovacích metod bude vycházet z kombinací těchto několika jednoduchých komponent a jejich správného nastavení. Doporučuji s nimi experimentovat a vyzkoušet si připravit různá rozložení formulářů.
Pokud máte jakékoliv dotazy nebo připomínky, přidejte je do diskuse pod článkem.