Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 7 - Kreslení na Graphics v C# .NET

V předešlém cvičení, Řešené úlohy k 3.-6. lekci Windows Forms v C# .NET, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

Již umíme vytvořit poměrně sofistikované aplikace. Dnešní C# .NET tutoriál budeme věnovat kreslení.

Kreslení na Graphics

Vytvoříme aplikaci, která má za úkol zastřešit prodej vstupenek do kina. Jak víme, v sálu je mnoho sedadel a pracovník kina by měl v aplikaci vidět, která sedadla jsou již obsazená. Možná by vás napadlo naklikat pro sedadla PictureBoxy. Pokud by však kino mělo 15 řad a každá řada 30 sedadel, máme to 450 PictureBoxů. Asi tušíte, že existuje lepší cesta, než začít bušit PictureBox1, PictureBox2... A jak by se potom obsluhovaly? V případě, že potřebujeme vykreslit něco náročnějšího, než jen jeden nebo dva obrázky, využijeme Graphics. To spočívá v tom, že na formulář umístíme jeden PictureBox a na jeho plátno budeme vykreslovat to, co potřebujeme.

Aplikaci značně zjednodušíme, není třeba aby byla složitá. Bude umět zobrazit jen jeden sál, který bude zpočátku prázdný. Uživatel nakliká myší obsazená sedadla a poté stiskne tlačítko Uložit, které do zvolené lokace uloží jednoduchý txt soubor s informací o obsazenosti sálu. Ukládání si zkusíme proto, abychom se naučili pracovat s dialogy.

Návrh formuláře

Vytvořte si novou Windows Forms Aplikaci, formulář přejmenujeme na KinoForm, záhlaví třeba na Evidence kinosálu. Přes většinu formuláře natáhněte PictureBox, který pojmenujeme kinoPictureBox. Pod PictureBox přijde Button se jménem ulozitButton a textem Uložit. Konečně na formulář přetáhněme i SaveFileDialog. Ten se nepřidá přímo na formulář, ale do lišty pod něj. Nejedná se totiž o formulářový prvek, ale pouze o pomocnou komponentu. Přejmenujeme ji na kinoSaveFileDialog. Můžete si pohrát s kotvami a podobně. Váš formulář by měl vypadat asi takto:

Formulář kinosálu v C# .NET - Windows Forms - Okenní aplikace v C# .NET

Logická vrstva

Asi vás nepřekvapí, že k aplikaci přidáme třídu Kinosal. Bude mít jeden privátní atribut, kterým bude dvourozměrné pole sedadel. Pokud jste s 2D polem ještě nepracovali, tak si ho můžete představit jako tabulku. Jednorozměrné (klasické) pole je vlastně jen jeden řádek. S 2D polem poté pracujeme úplně stejně, jako s jednorozměrným, jen musíme uvést dvě souřadnice (X a Y). V mnoha jazycích se dělá 2D pole jako pole polí, C# umí definovat přímo 2d pole a to takto:

class Kinosal
{
    private bool[,] sedadla = new bool[30, 15];

}

Sedadla jsou typu bool, protože nás zajímá jen jestli je volné nebo obsazené. 30 je šířka pole, 15 jeho výška.

Do třídy ještě přidáme 2 privátní konstanty, jedna udává velikost vykreslovaného sedadla v pixelech a druhá mezeru mezi sedadly v pixelech. Zvykněte si konstanty používat, až budete chtít sedadla zvětšit, stačí pouze přepsat jednu konstantu a nemusíte luštit vykreslovací kód.

private const int velikost = 16;
private const int mezera = 2;

Můžeme přejít k metodám.

Vykreslení

Kinosál by se měl umět vykreslit. Již jsme si zmínili, že budeme kreslit na plátno. Toto plátno je typu Graphics a necháme si ho přijít v parametru metody Vykresli(). Pro typ Graphics je třeba přidat using System.Drawing, ale to vás jistě nezaskočilo. Na plátno se potom kreslí pomocí jeho metod. Nás bude zatím zajímat jen metoda FillRectangle(), která vykreslí obdélník, vyplněný určitou barvou. Metod je tam obrovská spousta pro různé geometrické tvary, ať už vyplněné nebo nevyplněné. Můžete si je projet, některé si vyzkoušíme ještě v dalších lekcích.

V Graphics rozeznáváme dva typy barvy - barva výplně (Brush = štětec) a barva obrysu (Pen = pero). Pro vyplněný obdélník musíme zadat nějaký Brush. Hotové instance nastavené na určité barvy nalezneme na statické třídě Brushes (nebo pro obrysy Pens), stačí si jen vybrat. Štětce mohou kreslit i nějakými vzory nebo obrázky, ale to pro nás není důležité.

Pomocí dvou vnořených cyklů projedeme všechna sedadla v poli a na plátno vykreslíme buď zelený nebo červený čtverec. Vnějším cyklem budeme projíždět řádky, vnitřním sloupce v aktuálním řádku. Barvu (přesněji štětec) určíme podle toho, zda je sedadlo na dané souřadnici true nebo false. Kód metody bude následující:

public void Vykresli(Graphics g)
{
    Brush brush;
    for (int j = 0; j < sedadla.GetLength(1); j++)
    {
        for (int i = 0; i < sedadla.GetLength(0); i++)
        {
            if (sedadla[i, j])
                brush = Brushes.Red;
            else
                brush = Brushes.Green;
            g.FillRectangle(brush, i * (velikost + mezera), j * (velikost + mezera), velikost, velikost);
        }
    }
}

Všimněte si, že v cyklech nepoužíváme hodnoty 30 a 15, ale používáme metodu GetLength() s parametry 0 a 1. Tato metoda slouží pro získání velikosti dvourozměrného pole. 0 je šířka, 1 je výška (samozřejmě záleží na nás, kterou dimenzi si určíme jako výšku a kterou jako šířku). Pevnou velikost neuvádíme pochopitelně z důvodu, že v budoucnu můžeme pole zvětšit/zmenšit a museli bychom v kódu hledat kde všude jsme hodnoty 30 a 15 použili. Těmto problémům je vždy lepší se vyhnout a pracovat s délkou pole.

Za zmínku stojí i samotné vykreslení obdélníku. Prvním parametrem metody FillRectangle() je Brush, určující barvu výplně. Další dva parametry jsou souřadnice levého horního rohu obdélníku. Poslední dva parametry určují jeho výšku a šířku. Jelikož je každé sedadlo široké 16 pixelů + 2 pixely mezera, musíme jeho souřadnici touho hodnotou pronásobit. Pokud je v i např. hodnota 2 (kreslíme tedy 3. sloupec), kreslíme na X souřadnici 36, nikoli na 2 :) To samé platí pro souřadnici Y.

Později si můžete zkusit nahradit FillRectangle() metodou FillOval(). Funguje úplně stejně, ale vykreslí elipsu. Určitě si po dokončení aplikace zkuste vykreslit i další tvary.

Propojení formuláře s logickou vrstvou

Základ logiky máme hotový, pojďme ji propojit s formulářem. Přejdeme do kódu formuláře a ve třídě vytvoříme privátní instanci kinosálu:

private Kinosal kinosal = new Kinosal();

Nyní naklikneme PictureBoxu událost Paint. Musíte to udělat přes ikonu blesku v oknu Properties. Událost volá systém ve chvíli, kdy se má okno překreslit. To je samozřejmě v případě spuštění aplikace, ale také po obnovení z minimalizace, ve chvíli, kdy po okně aplikace přejedeme jiným oknem a podobně.

V obslužné metodě události zavoláme na instanci kinosálu metodu Vykresli(). Plátno nám přijde jako vlastnost parametru události. Pouze ho předáme dále metodě logiky, která nám na něj vykreslí.

private void kinoPictureBox_Paint(object sender, PaintEventArgs e)
{
    kinosal.Vykresli(e.Graphics);
}

Za výsledek se nemusíme stydět:

Kreslení tvarů na PictureBox v C# .NET - Windows Forms - Okenní aplikace v C# .NET

V příští lekci, Zpracování kliknutí na souřadnice v C# .NET, si ukážeme, jak kliknutím na určité sedadlo změnit jeho stav a zprovozníme také ukládání. Projekt máte jako vždy ke stažení v příloze pro případ, že se vám něco nepodařilo.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 1182x (50.2 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Řešené úlohy k 3.-6. lekci Windows Forms v C# .NET
Všechny články v sekci
Windows Forms - Okenní aplikace v C# .NET
Přeskočit článek
(nedoporučujeme)
Zpracování kliknutí na souřadnice v C# .NET
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
31 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity