IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
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 6 - Upomínač narozenin v C# .NET WPF - Návrh oken

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

V dnešním WPF tutoriálu začneme programovat Upomínač narozenin přátel. Hotová aplikace bude vypadat takto:

upomínač narozenin wpf - WPF - Okenní aplikace v C# .NET

Vidíme, že aplikace má 2 formuláře, používá ovládací prvky pro práci s datem a také obsahuje ukládání dat do souborů. Vnitřně narazíme na architekturu Model-View-ViewModel, výjimky a bindingy. Nebude toho málo, ale vše si postupně vysvětlíme a jistě to zvládneme. Aplikace je ještě poměrně jednoduchá a nejlépe se látka naučí na praktickém příkladu.

Návrh formulářů

Začněme tradičně návrhem formulářů. Vytvoříme si nový WPF projekt s názvem UpominacNarozenin.

Hlavní formulář

Formuláři nastavíme titulek okna, startovní pozici na obrazovce a můžeme i nějakou ikonku.

Rozložení

Možností jak dospět toho samého výsledků při rozložení formuláře je více. My si jeho <Grid> rozdělíme následujícím způsobem:

upomínač narozenin grid hlavní okno - WPF - Okenní aplikace v C# .NET

Tabulka má 2 sloupce a 4 řádky. Řádky jsou vysoké postupně: 20, 30, * a 30 DIP. Ten předposlední se tedy roztahuje s oknem. Levý sloupec má šířku *, pravý má pevnou šířku 200 DIP. Kolem celého elementu <Grid> je Margin 10 DIP. Kód v elementu Grid vypadá nyní následovně:

<Grid Margin="10">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="200"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="30"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>

</Grid>

Horní elementy <TextBlock>

V prvních dvou řádcích elementu <Grid> jsou vložené elementy <TextBlock> s informací o dnešním datu a nejbližších narozeninách. Text se zde skládá z několika částí a ačkoli lze v každém řádku použít pouze jeden <TextBlock>, do kterého hodnotu složíme, my si pro zjednodušení vložíme několik elementů <TextBlock> vedle sebe.

Element <StackPanel>

Pro skládání ovládacích prvků vedle sebe nebo pod sebe slouží <StackPanel>. Jedná se o kontejner na další prvky, stejně jako <Grid>. Do každého řádku tabulky vložíme jeden <StackPanel>. Budeme chtít, aby se <StackPanel> nevložil pouze do prvního sloupce, ale zasahoval do celého řádku. Proto mu zadáme atribut ColumnSpan s hodnotou 2, což znamená, že zasahuje přes 2 sloupce. Je to podobné jako colspan v HTML nebo jako když spojujeme buňky tabulky v Excelu. Stejně tak existuje RowSpan, který vkládá element přes více řádků. Elementům <StackPanel> ještě nastavíme atribut Orientation na hodnotu Horizontal, výchozí je totiž Vertical, tedy řazení pod sebe. Rovnou do nich také vložíme jednotlivé elementy <TextBlock>, text těch, kde se mají zobrazovat data, ponecháme zatím prázdný.

<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"  Orientation="Horizontal">
    <TextBlock Text="Dnes je " />
    <TextBlock Text="" />
</StackPanel>

<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal">
    <TextBlock Text="Nejbližší narozeniny má " />
    <TextBlock Text="" />
    <TextBlock Text=" za " />
    <TextBlock Text="" />
    <TextBlock Text=" dní." />
</StackPanel>

Spodní tlačítka

Úplně stejným způsobem vložíme do posledního řádku okna dvě tlačítka. Opět budou v elementu <StackPanel> (protože je chceme vedle sebe) a ten bude opět zasahovat přes 2 sloupce. <StackPanel> se bude centrovat. Tlačítkům rovnou přiřadíme jména, jelikož je budeme používat v Code Behind. Levému nastavíme pravý Margin, aby nebyla nalepená úplně na sobě:

<StackPanel Grid.Row="3" Grid.Column="0" 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>

Náš formulář nyní vypadá takto:

upomínač narozenin první návrh okna - WPF - Okenní aplikace v C# .NET

Můžeme si aplikaci zkusit spustit a okno rozšířit, s kontrolou, zda se vše přizpůsobuje.

Element <ListBox>

Uložené osoby budeme zobrazovat v ovládacím prvku <ListBox>. Jak již název napovídá, jedná se o nějaký seznam položek. <ListBox> je v podstatě rozbalený <ComboBox>, pracuje se s ním úplně stejně. V našem případě nebudeme položky definovat v kódu XAML, ale načteme je později z logické vrstvy aplikace. <ListBox> vložíme do 1. sloupce a 3. řádku, pojmenujeme 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"/>

Element <StackPanel>

Zbývá vložit jen kalendář a nad něj opět několik elementů TextBlock. Můžeme si v dané buňce buď udělat další <Grid> nebo použít <StackPanel>, který je na řazení prvků pod sebe dělaný. Tomu nastavíme levý Margin na 10 DIP. V každém řádku opět potřebujeme 2 elementy <TextBlock> vedle sebe, budou tedy v dalších elementech <StackPanel>. Kalendář vložíme jako ovládací prvek <Calendar>, slouží sice spíše pro výběr data, ale my jej budeme používat pro jeho zobrazení.

<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ář máme hotový.

Dialog pro přidání osoby

K projektu přidáme nové okno (kliknutím pravým tlačítkem na projekt v Solution Explorer -> Add -> Window), které pojmenujeme OsobaWindow. Opět si nastavíme titulek, startovní pozici a ikonku.

Ukažme si znovu obrázek hotových formulářů, nyní pracujeme na tom vpravo:

upomínač narozenin - WPF - Okenní aplikace v C# .NET

Rozložení

<Grid> rozdělíme opět na 2 sloupce a 4 řádky. Výšky řádků jsou následující: 4*, 30, 30, *. První a poslední řádek se tedy roztahují s oknem, první zabere 4x více prostoru než poslední. Oba sloupce budou mít šířku *, ta je výchozí, nemusíme ji tedy ani definovat. Okolo celého Gridu necháme opět Margin 10. Výsledek vypadá takto:

upomínač narozenin grid osoba - WPF - Okenní aplikace v C# .NET

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>

Element Image

Do prvního řádku vložíme nějaký obrázek, abychom se s nimi naučili pracovat. Spoustu ikon volně ke stažení nalezneme na tomto webu, na kterém si přečtěte licenci pro jaké případy je možno danou ikonu použít. Obrázek vložíme pomocí ovládacího prvku <Image>. Soubor obrázku (nejčastěji .png) musíme podobně jako ikonu nejprve přidat do projektu. Poté název souboru uvedeme v atributu Source prvku <Image>. Když máme obrázků v projektu již hodně, vyplatí se na ně vytvořit nějakou složku. Výchozí chování obrázků je, že se roztahují tak, aby vyplnily rodičovský prvek. To nám zde nevyhovuje a proto nastavíme Stretch na hodnotu "None". Obrázek vložíme do celého řádku tabulky pomocí ColumnSpan:

<Image Source="osoba_pridat.png" Stretch="None" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0"/>

Element <Label>

Do druhého sloupce dalších dvou řádků přijdou ovládací prvky k zadání jména a data narození. Ke každému prvku umístíme do prvního sloupce popisek. Nepoužijeme k tomu však <TextBlock>, ale <Label>. <Label> je popisek, který se vztahuje k určitému prvku. Pokud do textu jeho popisku vložíme podtržítko před nějaké písmeno, definujeme tak klávesovou zkratku. Po stisknutí Alt + tohoto písmena se zaktivní ovládací prvek, ke kterému popisek patří.

Podtržítko bychom v elementu <Label> napsali jako dvě za sebou.

K zadání jména použijeme samozřejmě <TextBox>. K zadání data narození použijeme ovládací prvek <DatePicker>. Ukaž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 propojení elementu <Label> s ovládacím prvkem je realizované pomocí atributu Target. Zde je výraz ve složených závorkách, který začíná výrazem Binding. Binding označuje provázání, zde <Label> na prvek s určitým jménem. Setkáme se s ním ještě na mnoha místech. Zbytek kódu by neměl být nic nového. Nyní ještě nemůžeme formulář ve spuštěné aplikaci zobrazit, ale až to půjde a stiskneme na něm Alt + J, zaktivní se pole se jménem. Alt + D zaktivní DatePicker.

Dialog dokončíme vložením potvrzovacího tlačítka. To se bude zobrazovat dole ve středu posledního řádku.

<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 ve WPF ještě přiřadit co mají dělat výchozí a ukončovací klávesy. Výchozí klávesa je Enter a měla by vyvolat stisk tlačítka OK. Ukončovací klávesa je Esc. Proto tlačítku přidáme ještě atribut IsDefault="True".

Pokud bychom chtěli, aby se dialog zavřel stisknutím Esc, přidali bychom zavírací tlačítko s nastaveným atributem IsCancel na hodnotu True.

Tak a máme hotovo.

V příští lekci, Upomínač narozenin v C# .NET WPF - Logická vrstva, to bude čistě o logické části aplikace a C# kódu, o kterou rozšíříme naši aplikaci Upomínač narozenin.


 

Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.

Stáhnout

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

Staženo 951x (419.63 kB)

 

Předchozí článek
Řešené úlohy k 1.-5. lekci WPF v C# .NET
Všechny články v sekci
WPF - Okenní aplikace v C# .NET
Přeskočit článek
(nedoporučujeme)
Upomínač narozenin v C# .NET WPF - Logická vrstva
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
86 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