11. diel - Kreslenie na Canvas v C # .NET WPF
V predchádzajúcom cvičení, Riešené úlohy k 6.-10. lekciu WPF v C # .NET, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Riešené úlohy k 6.-10. lekciu WPF v C # .NET , 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 WPF tutoriál budeme venovať kreslenie.
Kreslenie na Canvas
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á Button
y. Ak by však kino malo 15 radov a každá rada 30
sedadiel, máme to 450 Button
ov. Asi tušíte, že existuje
lepšia cesta, než začať búšiť Button1
,
Button2
... 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 Canvas
, česky plátno. To spočíva v tom,
že na formulár umiestnime jeden Canvas
a do neho
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ú WPF Aplikáciu, titulok okna nastavme na
Evidence kinosálu
. Oknu nastavte vlastnosť
WindowStartupLocation
na hodnotu CenterScreen
. Tým
zabezpečíme, že sa okno pri spustení aplikácie zobrazí v strede
obrazovky.
Pre návrh formulára využijeme z predošlých lekcií už iste dobre známy
prvok Grid
. Vzhľad aplikácie nie je nijako zložitý, a tak si
mriežku rozdelíme na dva riadky. Jeden riadok bude obsahovať
Canvas
a v druhom bude Button
s textom
Uložit
. U tlačidla si ešte pridáme udalosť Click
a necháme si vygenerovať metódu v Code Behind, ktorá sa vždy zavolá, keď
používateľ na tlačidlo klikne. Váš formulár by mal vyzerať asi
takto:
A tu je jeho zodpovedajúce XAML kód:
<Window x:Class="Kino.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-;;compatibility/2006" xmlns:local="clr-namespace:Kino" mc:Ignorable="d" Title="Evidence kinosálu" WindowStartupLocation="CenterScreen" Height="450" Width="600"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="350"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Canvas Name="MyCanvas" Margin="20 50 0 0"></Canvas> <Button Name="Ulozit" Click="Ulozit_Click" Content="Uložit" Grid.Row="1" Height="20" Width="100"></Button> </Grid> </Window>
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.
Vloženie obdĺžnikov
Už sme si spomenuli, že budeme kresliť na plátno. Jednotlivé obdĺžniky
reprezentujúci sedadlá budú reprezentované ako objekty, ktoré na plátno
vložíme pomocou metódy VlozObdelniky()
. Toto plátno typu
Canvas
a necháme si ho prísť v parametri metódy. Je potrebné
pridať menný priestor using System.Windows.Shapes
, ktorý nám
sprístupní triedu Rectangle
(obdĺžnik). Keď budeme jednotlivé
obdĺžniky vkladať na Canvas
, tak im vždy nastavíme šírku a
výšku na konštantu velikost
a ďalej nastavíme príslušnú
farbu vo vlastnosti Fill
pomocou statickej triedy
Brushes
. Tá obsahuje hotové inštancie nastavenej na určité
farby, stačí si len vybrať.
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 VlozObdelniky(Canvas MyCanvas) { for (int j = 0; j < sedadla.GetLength(1); j++) { for (int i = 0; i < sedadla.GetLength(0); i++) { Rectangle rectangle = new Rectangle { Height = velikost, Width = velikost, }; rectangle.Fill = sedadla[i, j] ? Brushes.Red : Brushes.Green; MyCanvas.Children.Add(rectangle); Canvas.SetLeft(rectangle, i * (velikost + mezera)); Canvas.SetTop(rectangle, j * (velikost + mezera)); } } }
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. Môžeme vidieť, že
vykreslenie prebieha tak, že sa každá inštancia Rectangle
pridá ako potomok do nášho Canvasu
. Potom aby sa obdĺžniky
zobrazili presne tam, kde chceme, tak je nutné ešte nastaviť ich pozíciu.
Využijeme statickú triedu Canvas
, ktorá obsahuje metódy
SetLeft()
a SetTop()
, ktoré predstavujú súradnice
ľavého horného rohu obdĺžnika. 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.
Prepojenie formuláre s logickou vrstvou
Základ logiky máme hotový, poďme ju prepojiť s formulárom. Prejdeme do Code Behind formulára a vytvoríme privátne inštanciu kinosály:
private Kinosal kinosal = new Kinosal();
Teraz už je to naozaj veľmi jednoduché. Na inštanciu kinosály zavoláme
metódu VlozObdelniky()
a ako parameter jej odovzdáme náš
Canvas
, ktorý sme si definovali vo formulári. Aby došlo k
vykreslenie pri štarte aplikácie, tak tento kód umiestnite v Code Behind do
konstruktoru formulára.
public MainWindow()
{
InitializeComponent();
kinosal.VlozObdelniky(MyCanvas);
}
Za výsledok sa nemusíme hanbiť:
V budúcej lekcii, Spracovanie kliknutí na obdĺžnik v C # .NET WPF , 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.