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é 1018x (419.63 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#