Canvas, StackPanel, WrapPanel

8. díl - Canvas, StackPanel, WrapPanel

Tomáš Jecha, MVP, MCSD       22.03.2012       C#, VB.NET, WPF, Komponenty, .NET       17748 zobrazení

Článek se věnuje dalším široce používaným pozicovacím komponentám WPF. Canvas pro absolutní pozicování, StackPanel pro skládání elementů vedle sebe nebo nad sebe a WrapPanel zalamující jejich tok do řádků nebo sloupců.

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>

WPF Canvas 1

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>

WPF Canvas 2

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>

WPF StackPanel 1

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>

WPF StackPanel 2

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>

WPF 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:

WPF WrapPanel

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>

WPF Grid + WrapPanel

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.

 

hodnocení článku

4 bodů / 4 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Všechny díly tohoto seriálu

 

Mohlo by vás také zajímat

Jednoduchý scheduler v .NETu

Asi to znáte – máte nějaký složitější systém na zpracování velkého objemu dat a čas od času potřebujete vykovat nějakou automatizovanou údržbu – typicky smazat všechny položky starší než několika dní. Možností, jak toho dosáhnout, je hodně. Snažil jsem se vymyslet něco jednoduchého a efektivního.

ASP mvc–from zero to hero (3), vývojový stack a solution

Code First initializers a migrace - kompletní přehled

 

 

Nový příspěvek

 

Super clanok

Super clanok dik :-)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Canvas, StackPanel, WrapPanel

Urcite by som este spomenul DockPanel. Ked sa pozrieme na klasicke desktopove apliakcie, tak je to vacsinou je zakladny layout typu DockPanel!

http://www.wpftutorial.net/DockPanel.htm...

napr browser je zhruba takto:

<DockPanel LastChildFill="True">

<uc:TabBar DockPanel.Dock="Top" />

<uc:ToolBar DockPanel.Dock="Top" />

<uc:AdressBar DockPanel.Dock="Top" />

<uc:StatusBar DockPanel.Dock="Bottom" />

<uc:SideBar DockPanel.Dock="Left" />

<Label Content="Volna Plocha" />

</DockPanel>

ked sa pozriem na visual studio, tak to je krasny priklad na DockPanel.

z parcovnej plochy si zoberiem kus zhona, na menu, potom dalsie kusy zhora na toolbary, potom si zoberiem nieco zlava (toolbox), nieco z prava (solution explorer). Ostane mi miesto na kod, z ktoreho este odkrojim kus pre okna ako (ErrorList, Output atd).

Tiez, keby som chcel usporiadat prvky zdola nahor (ako stackpanel, ale naopak) alebo zprava dolava, tak musim pouzit DockPanel.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

A to se zrovna pletete. Právě ono zmiňované Visual Studio používá k většině pozicovacích úkonů Grid a ne DockPanel ;-). Důvodem, proč například právě ve Visual Studiu nebyl použit, jen ten, že se hodí jen na omezenou množinu jednodušších úkonů. Ale tím samozřejmě neříkám, že důležitý není. Věnovat se mu určitě ještě budu.

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

vydávání se trošku zadrhlo... škoda

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Bohužel jsem musel psaní na pár týdnů z časových důvodů pozastavit. Nyní jsem vydávání obnovil, vypublikoval další článek a připravuji další díly.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback