6. diel - PRIPOMIENKOVÉ narodenín v C # .NET WPF - Návrh okien
V predchádzajúcom cvičení, Riešené úlohy k 1.-5. 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 1.-5. lekciu WPF v C # .NET , sme doprogramovali jednoduchú kalkulačku. Počas nasledujúcich niekoľkých C# .NET tutoriálov si vytvoríme stredne pokročilú aplikáciu. Bude sa jednať o pripomienkovej narodenín priateľov. Hotová aplikácia bude vyzerať takto:

Vidíme, že aplikácia má 2 formulára, používa ovládacie prvky pre prácu s dátumom a tiež obsahuje ukladanie dát do súborov. Vnútorne narazíme na architektúru Model-View-ViewModel, výnimky a binding. Nebude toho málo, ale všetko si postupne vysvetlíme a iste to zvládnete. Aplikácia je ešte pomerne jednoduchá a verím, že najlepšie sa látka naučí na praktickom príklade.
Návrh formulárov
Začnime tradične návrhom formulárov. Vytvorte si nový WPF projekt s
názvom UpominacNarozenin.
Hlavný formulár
Formulári nastavte titulok okna, štartovaciu pozíciu na obrazovke a môžete aj nejakú ikonku.
Rozloženie
Možností ako dospieť toho istého výsledkov pri rozložení formulára je
viac. My si jeho <Grid> rozdelíme nasledujúcim
spôsobom:

Tabuľka má 2 stĺpce a 4 riadky. Riadky sú vysoké postupne:
20, 30, * a 30 DIP. Ten
predposledný sa teda rozťahuje s oknom. Ľavý stĺpec má šírku
*, pravý má pevnú šírku 200 DIP. Okolo celého
elementu <Grid> je Margin 10 DIP.
Kód Grid u vyzerá teraz nasledovne:
<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="20"/> <RowDefinition Height="30"/> <RowDefinition Height="*"/> <RowDefinition Height="30"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="200"/> </Grid.ColumnDefinitions> </Grid>
Horný TextBlocky
V prvých dvoch riadkoch elementu <Grid> sú vložené
elementy <TextBlock> s informácií o dnešnom dátume a
najbližších narodeninách. Text sa tu skladá z niekoľkých častí a hoci
možno v každom riadku použiť iba jeden <TextBlock>, do
ktorého hodnotu zložíme, my si pre zjednodušenie vložíme niekoľko
elementov <TextBlock> vedľa seba.
StackPanel
Pre skladanie ovládacích prvkov vedľa seba alebo pod seba slúžia
<StackPanel>. Jedná sa o kontajner na
ďalšie prvky, rovnako ako <Grid>. Do každého riadku
tabuľky vložíme jeden <StackPanel>. Budeme chcieť, aby sa
<StackPanel> nevložil len do prvého stĺpca, ale zasahoval
do celého riadku. Preto mu zadáme atribút ColumnSpan s hodnotou
2, čo znamená, že zasahuje cez 2 stĺpce. Je to podobné ako
colspan v HTML alebo ako keď spájate bunky
tabuľky v Exceli. Rovnako tak existuje RowSpan, ktorý vkladá
element cez viac riadkov. StackPanelům ešte nastavíme atribút
Orientation na hodnotu Horizontal, predvolená je
totiž Vertical, teda radenie pod seba. Rovno do nich tiež
vložíme jednotlivé elementy <TextBlock>, text tých, kde
sa majú zobrazovať dáta, ponecháme zatiaľ prázdny.
<StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal"> <TextBlock Text="Dnes je "/> <TextBlock Text="" /> </StackPanel> <StackPanel Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal"> <TextBlock Text="Nejbližší narozeniny má "/> <TextBlock Text=""/> <TextBlock Text=" za "/> <TextBlock Text=""/> <TextBlock Text=" dní."/> </StackPanel>
Spodné tlačidlá
Úplne rovnakým spôsobom vložíme do posledného riadku okna dve
tlačidlá. Opäť budú vo StackPanelu (pretože ich chceme vedľa seba) a ten
bude opäť zasahovať cez 2 stĺpce. <StackPanel> sa bude
centrovať. Tlačidlám rovno priradíme mená, pretože ich budeme používať
v Code Behind. Ľavému nastavíme pravý Margin, aby nebola
nalepená úplne na sebe.
<StackPanel Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center"> <Button Width="100" Margin="0,0,10,0" Name="pridatButton" Content="Přidat"/> <Button Width="100" Name="odebratButton" Content="Odebrat"/> </StackPanel>
Váš formulár by mal teraz vyzerať asi takto:

Môžete si aplikáciu skúsiť spustiť a okno rozšíriť, aby ste skontrolovali, či sa všetko prispôsobuje.
Listbox
Uložené osoby budeme zobrazovať v ovládacom prvku
<ListBox>. Ako už názov napovedá, jedná sa o nejaký
zoznam položiek. <ListBox> je v podstate rozbalený
<ComboBox>, pracuje sa s ním úplne rovnako. V našom
prípade nebudeme položky definovať v XAML, ale načítame ich neskôr z
logickej vrstvy aplikácie. <ListBox> vložíme do 1. stĺpca
a 3. riadku, pomenujeme ho osobyListBox a nastavíme mu spodnú
Margin na 10 DIP.
<ListBox Name="osobyListBox" Grid.Column="0" Grid.Row="2" Margin="0, 0, 0, 10"/>
Kalendár
Zostáva vložiť len kalendár a nad neho opäť niekoľko TextBlocků.
Môžeme si v danej bunke buď urobiť ďalšie <Grid> alebo
použiť <StackPanel>, ktorý je na radenie prvkov pod seba
robený. Tomu nastavíme ľavý Margin na 10 DIP. V
každom riadku opäť potrebujeme 2 TextBlocky vedľa seba, budú teda v
ďalších StackPanelech. Kalendár vložíme ako ovládací prvok
<Calendar>, slúži síce skôr pre výber dátumu, ale my ho
budeme používať pre jeho zobrazenie.
<StackPanel Grid.Column="1" Grid.Row="2" Margin="10, 0, 0, 0"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Narozeniny: "/> <TextBlock Text="" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Věk: "/> <TextBlock Text="" /> </StackPanel> <Calendar Name="narozenCalendar" /> </StackPanel>
Hlavný formulár máme hotový.
Dialóg pre pridanie osoby
K projektu pridáme nové okno (kliknutím pravým tlačidlom na projekt v
Solution Exploreru -> Add -> Window), ktoré pomenujeme
OsobaWindow. Opäť si nastavte titulok, štartovaciu pozíciu a
ikonku.
Ukážme si znovu obrázok hotových formulárov, teraz pracujeme na tom vpravo:

Rozloženie
<Grid> rozdelíme opäť na 2 stĺpce a 4 riadky. Výšky
riadkov sú nasledujúce: 4*, 30, 30,
*. Prvý a posledný riadok sa teda rozťahujú s oknom, prvé
zaberie 4x viac priestoru ako posledný. Oba stĺpce budú mať šírku
*, tá je predvolený, nemusíme ju teda ani definovať. Okolo
celého Gridu necháme opäť Margin 10. Výsledok vyzerá
takto:

A jeho kód:
<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="4*"/> <RowDefinition Height="30"/> <RowDefinition Height="30"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> </Grid>
Image
Do prvého riadku vložíme nejaký obrázok, aby sme sa s nimi naučili
pracovať. Veľa ikon voľne k stiahnutiu nájdete na webe http://www.iconfinder.com, vždy si
prečítajte licenciu pre aké prípady môžete danú ikonu používať.
Obrázok vložíme pomocou ovládacieho prvku <Image>. Súbor
obrázka (najčastejšie .png) musíme podobne ako ikonu najprv
pridať do projektu. Potom názov súboru uvedieme v atribúte
Source prvku <Image>. Keď máme obrázkov v
projekte už veľa, oplatí sa na ne vytvoriť nejakú zložku. Predvolené
správanie obrázkov je, že sa rozťahujú tak, aby vyplnili rodičovský
prvok. To nám tu nevyhovuje a preto nastavíme Stretch na hodnotu
"None". Obrázok vložíme do celého riadku tabuľky pomocou
ColumnSpan.
<Image Source="osoba_pridat.png" Stretch="None" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0"/>
Label
Do druhého stĺpca ďalších dvoch riadkov prídu ovládacie prvky na
zadanie mena a dátumu narodenia. Ku každému prvku umiestnime do prvého
stĺpca popisok. Nepoužijeme k tomu však <TextBlock>, ale
<Label>. <Label> je popis, ktorý sa
vzťahuje k určitému prvku. Pokiaľ do textu jeho popisku vložíme
podčiarknik pred nejaké písmeno, definujeme tak klávesovú skratku. Po
stlačení Alt + tohto písmena sa zaktivní ovládací
prvok, ku ktorému popisok patrí. Ak vás napadlo, ako v texte Label teda
zapísať podčiarkovník, napíšete dve za sebou.
K zadanie mena použijeme samozrejme <TextBox>. K zadaní
dátumu narodenia použijeme ovládací prvok <DatePicker>.
Ukážme si kód:
<Label Content="_Jméno" Grid.Column="0" Grid.Row="1" Target="{Binding ElementName=jmenoTextBox}"/> <Label Content="_Datum narození" Grid.Column="0" Grid.Row="2" Target="{Binding ElementName=narozeninyDatePicker}"/> <TextBox Grid.Column="1" Grid.Row="1" Name="jmenoTextBox" Margin="0,0,0,5"/> <DatePicker Grid.Column="1" Grid.Row="2" Name="narozeninyDatePicker" Margin="0,0,0,5"/>
Vidíme, že prepojenie Label s ovládacím prvkom je realizované pomocou
atribútu Target. Tu je výraz v zložených zátvorkách, ktorý
začína slovom Binding. Binding označuje previazanie, tu label na
prvok s určitým menom. Stretneme sa s ním ešte na mnohých miestach. Zvyšok
kódu by nemal byť nič nové. Teraz ešte nemôžeme formulár v spustenej
aplikácii zobraziť, ale až to pôjde a stlačíte na ňom Alt +
J, zaktivní sa pole s menom. Alt + D zaktivní
DatePicker.
Dialóg dokončíme vložením potvrdzovacieho tlačidla. To sa bude zobrazovať dole v stredu posledného riadku.
<Button Name="okButton" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="100" Content="OK"/>
Každému oknu môžeme vo WPF ešte priradiť čo majú robiť predvolené a ukončovacie klávesy. Predvolené klávesa je Enter a mala by vyvolať stlačenie tlačidla OK. Ukončovacie klávesa je Esc. Preto tlačidlu pridáme ešte atribút:
IsDefault="True"
Ak by sme chceli, aby sa dialóg zavrel stlačením Esc,
najjednoduchšie je pridať Zatvárací tlačidlo a tomu nastaviť atribút
IsCancel na True.
Tak a máme hotovo. Myslím, že ste si užili navrhovaní formulárov v XAML do sýtosti naučili sa zas niečo nové. V budúcej lekcii, PRIPOMIENKOVÉ narodenín v C # .NET WPF - Logická vrstva , to bude čisto o logické časti aplikácie a C# kódu. Navrhnutý formulár je ako vždy k stiahnutiu nižšie.
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é 1124x (419.63 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

David sa informačné technológie naučil na