7. diel - Kreslenie na Graphics v C # .NET
V minulej lekcii, PRIPOMIENKOVÉ narodenín - Ukladanie dát a záver , sme dokončili tvorbu pripomienkovej narodenín. Vyskúšali sme si na ňom základné formulárové prvky a tiež binding a prácu s chybovými stavmi. Už vieme vytvoriť pomerne sofistikované aplikácie. Dnešné C# .NET tutoriál budeme venovať kreslenie.
Kreslenie na Graphics
Vytvoríme aplikáciu, ktorá má za úlohu zastrešiť predaj vstupeniek do
kina. Ako vieme, v sály je veľa sedadiel a pracovník kina by mal v aplikácii
vidieť, ktorá sedadlá sú už obsadená. Možno by vás napadlo naklikať pre
sedadlá PictureBox
y. Ak by však kino malo 15 radov a každá
rada 30 sedadiel, máme to 450 PictureBox
ov. Asi tušíte, že
existuje lepšia cesta, než začať búšiť PictureBox1
,
PictureBox2
... A ako by sa potom obsluhovali? V prípade, že
potrebujeme vykresliť niečo náročnejšieho, než len jeden alebo dva
obrázky, využijeme Graphics
. To spočíva v tom, že na formulár
umiestnime jeden PictureBox
a na jeho plátno
budeme vykresľovať to, čo potrebujeme.
Aplikáciu značne zjednodušíme, nie je potrebné aby bola zložitá. Bude vedieť zobraziť len jeden sála, ktorý bude spočiatku prázdny. Užívateľ naklikať myšou obsadená sedadla a potom stlačí tlačidlo Uložiť, ktoré do zvolenej lokácie uloží jednoduchý txt súbor s informáciou o obsadenosti sály. Ukladanie si skúsime preto, aby sme sa naučili pracovať s dialógmi.
Návrh formulára
Vytvorte si novú Windows Forms Aplikáciu, formulár premenujeme na
KinoForm
, záhlavie potrebné na Evidence kinosálu
.
Cez väčšinu formuláre natiahnite PictureBox
, ktorý pomenujeme
kinoPictureBox
. Pod PictureBox
príde
Button
s menom ulozitButton
a textom
Uložit
. Konečne na formulár pretiahnete i
SaveFileDialog
. Ten sa nepridá priamo na formulár, ale do lišty
pod neho. Nejedná sa totiž o formulárový prvok, ale len o pomocnú
komponentu. Premenujeme ju na kinoSaveFileDialog
. Môžete sa
pohrať s kotvami a podobne. Váš formulár by mal vyzerať asi takto:
Logická vrstva
Asi vás neprekvapí, že k aplikácii pridáme triedu Kinosal
.
Bude mať jeden privátne atribút, ktorým bude dvojrozmerné pole
sedadiel. Ak ste s 2D poľom ešte nepracovali, tak si ho môžete predstaviť
ako tabuľku. Jednorozmerné (klasické) pole je vlastne len jeden riadok. S 2D
poľom potom pracujeme úplne rovnako, ako s jednorozmernými, len musíme
uviesť dve súradnice (X a Y). V mnohých jazykoch sa robí 2D pole ako pole
polí, C# vie definovať priamo 2d poľa a to takto:
class Kinosal { private bool[,] sedadla = new bool[30, 15]; }
Sedadlá sú typu bool
, pretože nás zaujíma len či je
voľné alebo obsadené. 30
je šírka poľa, 15
jeho
výška.
Do triedy ešte pridáme 2 privátne konštanty, jedna udáva veľkosť vykreslovaného sedadla v pixeloch a druhá medzeru medzi sedadlami v pixeloch. Zvyknite si konštanty používať, až budete chcieť sedadlá zväčšiť, stačí len prepísať jednu konštantu a nemusíte lúštiť vykresľovací kód.
private const int velikost = 16; private const int mezera = 2;
Môžeme prejsť k metódam.
Vykreslenie
Kinosála by sa mal vedieť vykresliť. Už sme si spomenuli, že budeme
kresliť na plátno. Toto plátno typu Graphics
a necháme si ho
prísť v parametri metódy Vykresli()
. Pre typ
Graphics
treba pridať using System.Drawing
, ale to
vás iste nezaskočilo. Na plátno sa potom kreslí pomocou jeho metód. Nás
bude zatiaľ zaujímať len metóda FillRectangle()
, ktorá
vykreslí obdĺžnik, vyplnený určitou farbou. Metód je tam obrovská kopa
pre rôzne geometrické tvary, či už vyplnené alebo nevyplnené. Môžete si
ich prejsť, niektoré si vyskúšame ešte v ďalších lekciách.
V Graphics
rozoznávame dva typy farby - farba výplne
(Brush
= štetec) a farba obrysu (Pen
= pero). Pre
vyplnený obdĺžnik musíme zadať nejaký Brush
. Hotové
inštancie nastavenej na určité farby nájdeme na statické triede
Brushes
(alebo pre obrysy Pens
), stačí si len
vybrať. Štetce môžu kresliť aj nejakými vzory alebo obrázky, ale to pre
nás nie je dôležité.
Pomocou dvoch vnorených cyklov prejdeme všetky sedadlá v poli a na plátno
vykreslíme buď zelený alebo červený štvorec. Vonkajším cyklom budeme
prechádzať riadky, vnútorným stĺpce v aktuálnom riadku. Farbu (presnejšie
štetec) určíme podľa toho, či je sedadlo na dané súradnici
true
alebo false
. Kód metódy bude nasledujúci:
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šimnite si, že v cykloch nepoužívame hodnoty
30
a 15
, ale používame metódu
GetLength()
s parametrami 0
a 1
. Táto
metóda slúži na získanie veľkosti dvojrozmerného poľa. 0
je
šírka, 1
je výška (samozrejme záleží na nás, ktorú
dimenziu si určíme ako výšku a ktorú ako šírku). Pevnú veľkosť
neuvádzame pochopiteľne z dôvodu, že v budúcnosti môžeme pole zväčšiť
/ zmenšiť a museli by sme v kóde hľadať kde všade sme hodnoty
30
a 15
použili. Týmto problémom je vždy lepšie
sa vyhnúť a pracovať s dĺžkou poľa.
Za zmienku stojí aj samotné vykreslenie obdĺžnika. Prvým parametrom
metódy FillRectangle()
je Brush
, určujúci farbu
výplne. Ďalšie dva parametre sú súradnice ľavého horného rohu
obdĺžnika. Posledné dva parametre určujú jeho výšku a šírku. Keďže je
každé sedadlo široké 16 pixelov + 2 pixely medzera, musíme jeho súradnicu
za večnými hodnotou prenásobiť. Pokiaľ je v i
napr. Hodnota
2
(kreslíme teda 3. stĺpec), kreslíme na X súradnicu
36
, nie na 2
To isté platí pre súradnicu Y.
Neskôr si môžete skúsiť nahradiť FillRectangle()
metódou
FillOval()
. Funguje úplne rovnako, ale vykreslí elipsu. Určite
si po dokončení aplikácie skúste vykresliť aj ďalšie tvary.
Prepojenie formuláre s logickou vrstvou
Základ logiky máme hotový, poďme ju prepojiť s formulárom. Prejdeme do kódu formulára a v triede vytvoríme privátnej inštanciu kinosály:
private Kinosal kinosal = new Kinosal();
Teraz naklikne PictureBox
u udalosť Paint
. Musíte
to urobiť cez ikonu blesku v oknu Properties. Udalosť volá systém vo
chvíli, kedy sa má okno prekresliť. To je samozrejme v prípade spustenia
aplikácie, ale aj po obnovení z minimalizácie, vo chvíli, kedy po okne
aplikácie prejdeme iným oknom a podobne.
V obslužné metóde udalosti zavoláme na inštanciu kinosály metódu
Vykresli()
. Plátno nám príde ako vlastnosť parametra udalosti.
Iba ho odovzdáme ďalej metóde logiky, ktorá nám na neho vykreslí.
private void kinoPictureBox_Paint(object sender, PaintEventArgs e) { kinosal.Vykresli(e.Graphics); }
Za výsledok sa nemusíme hanbiť:
V budúcej lekcii, Riešené úlohy k 3.-6. lekciu Windows Forms v C # .NET , si ukážeme, ako kliknutím na určité sedadlo zmeniť jeho stav a sprevádzkujeme tiež ukladanie. Projekt máte ako vždy k stiahnutiu v prílohe pre prípad, že sa vám niečo nepodarilo.
V nasledujúcom cvičení, Riešené úlohy k 3.-6. lekciu Windows Forms v C # .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 1190x (50.2 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#