Články

Tisk článku Tisk článku

Grid

[Zpět na kategorii]

Datum: 16. 3. 2012 8:55       Autor: Tomáš Jecha       Zobrazeno: 3681x

Kategorie: Aplikace

Témata: VB.NET, C#

Seriál: Windows Presentation Foundation (WPF) - Díl 7.

Grid je jedna z nejdůležitější a nejpoužívanějších pozicovacích komponent ve WPF. Ulehčuje návrh formulářů a své uplatnění nachází v řadě scénářů.


Grid je pozicovací komponenta. Sama o sobě nemá žádný vzhled a stará se “jen” o rozdělení prvků do pomyslné mřížky, jejímž sloupcům a řádkům lze jednoduše, ale zároveň efektivně nastavovat způsob výpočtu šířky a výšky.

Pokud neuvedeme definici ani pro jeden sloupec, je celý Grid na svoji šířku jedním sloupcem. Stejně toto platí i pro řádky. Pokud neuvedeme ani jednu definici řádku, je celý Grid na svoji výšku jedním řádkem. To je důvod, proč můžeme do Gridu vkládat další komponenty i bez jakéhokoliv nastavování sloupců, či řádků a používat jej i jako primitivní panel.

Panel

Grid podobně jako řada dalších pozicovacích komponent (StackPanel, Canvas, DockPanel a další) dědí z abstraktní třídy Panel. Ta zajišťuje základní funkce pro komponenty, které mají za úkol se starat o rozložení komponent uvnitř sebe sama.

Možnosti samotné třídy Panel třídy jsou obrovské a hojně se používá ke zpracování vlastních rozložení. Lze využít prakticky ke všem návrhům, kdy je potřeba nějakým speciálním způsobem pozicovat elementy a nestačí na to základní sada komponent. Není to úplně běžné a ne vždy je to nutné, pokud to však potřebujete, jde to. Příkladem může být vytváření tag-cloudu nebo zobrazení fotek v nějakém nestandardním rozložení (pověšené na šňůře, naházené na hromadu a další designové obskurnosti), či vytváření vlastních rozložení, jako je tomu například u ovládacího menu Office – Ribbon.

Nastavení Gridu

Při práci s Grid komponentou rozdělujete ovládací prvky do sloupců a řádků. K definování se používají vlastnosti:

  • Vlastnost ColumnDefinitions – definice  sloupců – kolekce ColumnDefinition objektů
  • Vlastnost RowDefinitions – definice řádků – kolekce RowDefinition objektů

Základní nastavení šířky sloupců a výšky řádků

Asi nejdůležitější hodnotou je u definice sloupce ColumnDefinition jeho šířka Width. A u definice řádku RowDefinition jeho výška Height.

Takže například definice dvou řádků a tří sloupců může vypadat takto (použité vlastnosti vysvětlím v následujících odstavcích):

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="*" MinHeight="20" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" MinWidth="50" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
</Grid>

U každého řádku nebo sloupce lze velikost nastavit několik variant hodnot. Konkrétně tyto tři:

  • Absolutní
  • Automatická
  • Výplň

Nyní jednotlivé možnosti proberu.

Absolutní velikost

Použití absolutní velikosti je zcela identické jako při nastavování absolutní velikosti běžných elementů. Do hodnoty zapíšete číslo, které bude vzato jako absolutní šířka sloupce nebo výška řádku.

Tento jednoduchý příklad ukazuje, jak nadefinovat Grid se dvěma řádky o velikosti 50 a 80 device independent pixels:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="80" />
    </Grid.RowDefinitions>
</Grid>

Automatická velikost

Stejně jako absolutní velikost, i automatická velikost je při nastavování shodná s nastavováním automatické velikosti u běžných elementů. Zapisujeme ji tedy jako hodnotu Auto. To zajišťuje, že buňka bude široká / vysoká tolik, kolik bude vyžadovat její obsah.

Následující příklad ukazuje, jak nadefinovat 2 sloupce, kde první bude mít absolutní pevnou šířku 150 a druhý bude mít šířku automatickou dle jeho obsahu:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
</Grid>

Velikost typu “výplň”

Posledním typem velikost je “výplň”. Pokud takto označíte některý ze sloupců, či řádků, bude jejich šířka, či výška, vyplňovat zbývající místo v Gridu. Tato hodnota se zapisuje pomocí znaku hvězdičky *.

Příklad ukazuje, jak zapsat definici, kde má první a druhý řádek pevnou, třetí automatickou velikost podle svého obsahu a poslední, čtvrtý vyplňuje zbývající část Gridu:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="150" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
</Grid>

Definic s “hvězdičkou” lze zapsat i více. Volné místo se pak poměrově rozdělí mezi ně. Pokud bude tedy zbývat v Gridu na šířku 90 device-independent-pixels a budou nedeklarovány 3 sloupce se šířkou *, každý z nich bude široký 30 device-independent-pixels.

Pokud chcete poměr mezi sloupci změnit, lze doplnit před znak hvězdičky číslo určující poměr proti ostatním. Pokud číslo neuvedeme, bere se tento poměr jako 1*. Dále uvedený kód definuje 3 řádky, kde první a poslední jsou stejně veliké a prostřední je 2× větší:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" /><!-- 25% -->
        <RowDefinition Height="2*" /><!-- 50% -->
        <RowDefinition Height="*" /><!-- 25% -->
    </Grid.RowDefinitions>
</Grid>

Minimální a maximální velikost

U definice řádku i sloupce lze nastavit minimální a maximální velikost. U definice sloupců ColumnDefinition jsou to vlastnosti MinWidth (minimální šířka) a MaxWidth (maximální šířka). U definice RowDefinition zase logicky MinHeight (minimální výška) a MaxHeight (maximální výška).

Tento kód definuje 2 řádky, která budou poměrem 1:1 vyplňovat celou výšku Gridu. Zároveň bude zajištěno, že spodní řádek bude vysoký alespoň 50 device-independent-pixels.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" MinHeight="50" />
    </Grid.RowDefinitions>
</Grid>

Zobrazení v designéru

Užitečnou pomůckou při návrhu je designér. Pro jeho použití je důležité objekt Grid nejprve označit. To lze udělat jak přímo z designéru, tak i v XAML kódu zvolením požadovaného elementu Grid. Po takovém vybraní se znázorní jednotlivé sloupce a řádky. V jejich záhlaví je navíc vidět malým písmem hodnota vlastnosti Width pro sloupce nebo Height pro řádky:

WPF Grid - designer

Při najetí na hlavičku sloupce nebo řádku se otevře menu, kde může změnit typ velikosti sloupce. Z leva to je absolutní velikost, výplň (hvězdička) a automatická velikost:

image

A pokud vám z nějakého důvodu nevyhovuje zapisování definicí do kódu, je možné kliknutím do záhlaví nový sloupec nebo řádek přidat přímo z designéru.

Vkládání obsahu

Pokud do Gridu vložíte obsah a nenastavíte mu žádnou doplňující vlastnost, vždy bude daný obsah vložen do prvního sloupce, prvního řádků. To oceníte, pokud využíváte Grid jen jako jednoduchý kontejner na objekty a nechcete rozdělení na sloupce a řádky vůbec řešit.

Pro změnu sloupce nebo řádku, kam vnořený element patří, využijete vlastnosti “Grid.Column” a “Grid.Row”, kterou lze nastavit na všech elementech pořadové číslo sloupce nebo řádku (číslujeme od 0 pro první sloupec/řádek). Následující příklad ukazuje Grid rozdělený na 4 buňky (2 sloupce a 2 řádky), kde každá buňka obsahuje obarvený nápis:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Label Background="LightYellow" Content="Sloupec vlevo nahoře" />
    <Label Background="LightCoral" Content="Sloupec vpravo nahoře" Grid.Column="1" />
    <Label Background="LightGreen" Content="Sloupec vlevo dole" Grid.Row="1" />
    <Label Background="LightSkyBlue" Content="Sloupec vpravo dole" Grid.Row="1" Grid.Column="1" />
</Grid>

Poznámka: U elementů, které spadají do prvního sloupce nebo řádku nemusím explicitně nastavovat Grid.Column=”0” a Grid.Row=”0”. Pokud to však například kvůli přehlednosti chcete udělat, nic tím nezkazíte.

 

Výsledek zobrazuje 4 stejně veliké dlaždice, které si poměr velikostí drží i při změnách velikosti okna.

WPF Grid 1

Poznámka: Vlastnosti Grid.Column a jí podobné nad elementy ve skutečnosti neexistují (například Label nemá vlastnost Grid.Column). Byly přidány dodatečně pomocí tzv. attached properties.  Ty dovolují k existujícím komponentám přidávat další externí vlastnosti, ke kterým lze přistupovat v XAML kódu přímo, jako kdyby fyzicky existovaly nad třídou, se kterou pracujeme. Tomuto tématu se budu věnovat v dalších kapitolách. Pro začínající uživatele WPF je ale zbytečné se tímto zatím zaobírat.

ColumnSpan a RowSpan

Pomocí vlastností Grid.ColumnSpan a Grid.RowSpan můžete elementy nechat přetékat přes více buněk najednou. Toto nastavení je ve výchozím stavu na hodnotě 1 – tedy element zasahuje pouze do jedné buňky.

Například změnou Grid.ColumnSpan na hodnotu 2 můžete u předchozího příkladu nechat přetéct element skrz oba sloupce:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Label Background="LightYellow" Content="Sloupec vlevo nahoře" Grid.ColumnSpan="2" />
    <Label Background="LightGreen" Content="Sloupec vlevo dole" Grid.Row="1" />
    <Label Background="LightSkyBlue" Content="Sloupec vpravo dole" Grid.Row="1" Grid.Column="1" />
</Grid>

WPF Grid 2

Závěr

Tímto jsem pokryl základy nastavení a použití prvku Grid. V jednom z dalších dílů se budu věnovat pokročilejším funkcím použití (sdílená velikost sloupců mezi několika Gridy) a častým postupům při vnořování pozicovacích komponent.


> Na začátek

 

Hodnocení:

Hlasů: 13
Zvolte své hodnocení

Tomáš Jecha

Již několikátým rokem obhajuji ocenění Microsoft Most Valuable Professional. Pracuji ve společnosti AVAST jako architekt a vývojář interních systémů. Mimo to nabízím školení, konzultace a zakázkový vývoj. Na http://www.jecha.net naleznete více informací. Dále působím také jako lektor a konzultant v počítačové škole Gopas. V současné době se zajímám především o SQL Server a technologie přicházející s .NET Frameworkem 4.5. Společně s Tomášem Hercegem jsem napsal tento web a starám se o jeho administraci.

Podpořte vznik dalších článků

Související články

DílNázev článku 
Díl 1. Úvod do Windows Presentation Foundation (WPF) 19. 1. 2012
Díl 2. Architektura WPF – Dispatcher 26. 1. 2012
Díl 3. Jazyk XAML 2. 2. 2012
Díl 4. Architektura a objektový model WPF 9. 2. 2012
Díl 5. Device independent pixels 16. 2. 2012
Díl 6. Základy pozicování 23. 2. 2012
Díl 7. Grid 16. 3. 2012
Díl 8. Canvas, StackPanel, WrapPanel 22. 3. 2012
Díl 9. ContentControl, Button a TextBlock 10. 4. 2012
Díl 10. Návrh přihlašovacího formuláře - TextBox, PasswordBox, CheckBox a Label 20. 4. 2012

RSS Feed RSS Feed

Diskuse

Díky

Datum: 16.3.2012 13:03
Autor: neregistrovaný (92.62.224.12)
Hodnocení autora: není
Příspěvků: 0
Díky za skvělý článek, pozicování je ve WPF opravdu luxusní ve srovnání s WinForms, již žádné problémy s DPI, případně rozlišením obr.
 
           [Odpovědět]
 
Hodnocení: 3 Čekejte, prosím...

Dobrá práce

Datum: 22.3.2012 9:41
Autor: neregistrovaný (147.32.228.51)
Hodnocení autora: není
Příspěvků: 0
Dobrá práce, děkuji za tento seriál...
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Grid

Datum: 14.4.2012 9:45
Autor: neregistrovaný (82.208.57.182)
Hodnocení autora: není
Příspěvků: 0
Ve Visual studiu 2010 expres komponenta Grid není. Je to nedostatek edice expres nebo je v této verzi nahrazena něčím jiným. Děkuji za odpověď
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Grid

Datum: 22.4.2012 10:57
Autor: Tomáš Jecha
Hodnocení autora: 844
Příspěvků: 1476
Grid je k dispozici ve všech verzích .NET Frameworku podporujících WPF (od .NET 3.0). Nemluvíte náhodou o DataGrid pro zobrazování dat?

Pravděpodobně máte projekt založený pro .NET 3.5. Pokud jej založíte pro .NET 4, komponentu Grid budete mít k dispozici.

Pro .NET 3.5 není DataGrid v základní sadě komponent. Nicméně můžete využít WPF Toolkit (http://wpf.codeplex.com/ ), což je knihovna komponent obsahujících mimo jiných i DataGrid. Každopádně, pokud máte tu možnost, doporučuji využít odladěnější a propracovanější komponenty z .NET 4.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Grid

Datum: 3.5.2012 11:20
Autor: neregistrovaný (82.208.57.182)
Hodnocení autora: není
Příspěvků: 0
Hledal jsem komponentu Grid, ale přesto že mám nastaven .NET 4 tak jediné podobné je TableLayoutPanel. Děkuji za odpověď
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Grid

Datum: 3.5.2012 11:29
Autor: neregistrovaný (82.208.57.182)
Hodnocení autora: není
Příspěvků: 0
Už jsem Grid našel. Je třeba při zakládání nového projektu zvolit WPF Application a ne Windows Form application.
 
           [Odpovědět]
 
Hodnocení: -3 Čekejte, prosím...

Row\Column Index

Datum: 9.9.2012 18:52
Autor: neregistrovaný (213.210.195.130)
Hodnocení autora: není
Příspěvků: 0
Dobry den Tomasi,

Najprv by som rad podakoval za vsetky clanky - len mi je trochu luto, ze som na ne narazil az teraz a nie hned na zaciatku :)

U WPF mi vyslovene vadi len jedina vec a to su prave indexy u Row\Column - bohuzial sa tu neda pouzivat odkaz napriklad pomocou .Name, takze mi to pride hodne katastrofalne a prepisovat trosku zlozitejsi XAML (ked clovek potrebuje narvat tlacitko do existujuceho row\column) je vyslovene utrpenim...

Nema s tym problem nikto okrem mna? :)

Martin
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Row\Column Index

Datum: 9.9.2012 19:00
Autor: Tomáš Jecha
Hodnocení autora: 844
Příspěvků: 1476
Dobrý den,
to je poměrně běžný požadavek, který se dá celkem snadno řešit. Já osobně jsem si napsal vlastní Grid, který umožňuje vkládání automatických řádků bez nutnosti zapisovat RowIndex. Kód poskytnout nemohu, ale doporučuji se podívat například na: http://wpfcontrib.codeplex.com/wikipage?...

Sám tuto komponentu nevyužívám, ale minimálně vás správně nasměruje.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: Row\Column Index

Datum: 10.9.2012 17:32
Autor: neregistrovaný (213.210.195.130)
Hodnocení autora: není
Příspěvků: 0
Dobry den Tomasi,

To bohuzial ale prilis nepomoze ked je n rows a n columns :)

Ja to riesim tak, ze mam napisany MarkupExtensionReturnType, takze v XAML mozem pouzivat priamo names <Grid Grid.Row="{local:GetRowID Row_Main}">

Ale stale to nie je uplne ono (samozrejme hlavne kvoli tomu, ze designer to nezvladne...

Ak mate dopredu naplanovanu nejaku osnovu na dalsie clanky, velmi rad by som uvital dve kapitoly - zaludnosti WPF (viz. napriklad indexing u grid) a nejake doporucenia ako prejst v WinForms.

Este raz diky za super clanky!
Martin
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...
 

VBNET.CZ | © 2007 Tomáš Herceg, Tomáš Jecha | Kopírování a přejímání jakéhokoliv obsahu z tohoto webu je bez písemného svolení autorů zakázáno.