Lekce 5 - Upomínač narozenin - Propojení prezentační a logické vrstvy
V minulé lekci, Upomínač narozenin - Logická vrstva, jsme naprogramovali většinu logické vrstvy aplikace pro upomínání narozenin.
Dnes v C# .NET tutoriálu aplikaci zprovozníme.
Oddělení prezentace a logiky
Nyní máme dokončenou tzv. prezentační část aplikace (formuláře) a logickou část (třídy). Tyto 2 vrstvy se v aplikaci striktně oddělují, jelikož jinak je kód velmi nepřehledný. Nikdy byste neměli provádět výpočty, zápisy do souborů, databáze a podobné věci přímo v kódu formuláře! Vždy si vytvoříme třídu, která poskytuje příslušné metody a tuto třídu z formuláře pouze používáme. Logika zůstane ve třídě. Třída by naopak vůbec neměla vědět o formuláři. Neměla by tedy např. zobrazovat chybové hlášky, ale pouze vyvolávat v případě chyby výjimky. Je potom na formuláři, aby uživateli chybu zobrazil. Právě formulář je ta část aplikace, která s uživatelem komunikuje. Žádná jiná to nedělá.
Pokud vás napadlo, že naše jednoduchá kalkulačka, kterou jsme vytvořili v prvních lekcích kurzu, byla návrhově špatně, máte pravdu. Z důvodu jednoduchosti jsme napsali výpočty rovnou do obslužné metody tlačítka. Správně bychom měli mít nějakou třídu, která by výsledky počítala a tu bychom z formuláře pouze volali.
Dnes si tedy ukážeme, jak se to dělá správně.
Propojení prezentace a logiky
Přejdeme do zdrojového kódu formuláře PrehledForm a
třídě přidáme privátní atribut typu SpravceOsob, ve kterém
rovnou vytvoříme instanci správce:
private SpravceOsob spravceOsob = new SpravceOsob();
Instance správce se vytvoří při vytvoření formuláře a formulář s ní dále bude komunikovat a tak provádět úkony, které si přeje uživatel.
V konstruktoru formuláře nastavíme dnesLabel na aktuální
datum a ListBoxu nastavíme vlastnost DataSource na
BingList Osoby na správci osob. Tím napojíme
ListBox na BindingList, odteď bude zobrazovat jeho
obsah a pokud se do listu něco přidá, projeví se to i v
ListBoxu.
public PrehledForm()
{
InitializeComponent();
dnesLabel.Text = DateTime.Now.ToLongDateString();
osobyListBox.DataSource = spravceOsob.Osoby;
}
Přidávání a mazání osob
Abychom něco konečně také viděli, přejdeme k přidávání osob.
Nejprve přejdeme do kódu formuláře OsobaForm, kde si stejně
jako v předchozím formuláři připravíme správce osob jako privátní
atribut. Kdybychom zde i vytvořili jeho instanci, nebylo by nám to moc
platné, jelikož osoby by byly načtené ve správci v hlavním formuláři. A
načítat je znovu by bylo neefektivní. Necháme si tedy hotového a
načteného správce předat konstruktorem a uložíme ho do připravené
proměnné:
private SpravceOsob spravceOsob; public OsobaForm(SpravceOsob spravceOsob) { InitializeComponent(); this.spravceOsob = spravceOsob; }
Nyní naklikneme tlačítko OK a do správce přidáme osobu pomocí hodnot,
které uživatel do jednotlivých prvků zadal. K hodnotě v
TextBoxu přistoupíme pomocí vlastnosti Text, k
hodnotě v DateTimePickeru pomocí vlastnosti
Value.
Určitě si vzpomínáte, že metoda Pridej() vyvolá výjimku v
případě příliš krátkého jména nebo data v budoucnosti. Proto kód s
přidáním vložíme do bloku try, za kterým bude následovat
blok catch. Pokud výjimka v bloku try nastane,
program se ihned přesune do bloku catch, kde pomocí
MessageBoxu zobrazí chybovou hlášku. Pokud bychom výjimku takto
neošetřili, způsobila by pád aplikace.
private void okButton_Click(object sender, EventArgs e) { try { spravceOsob.Pridej(jmenoTextBox.Text, narozeninyDateTimePicker.Value); Close(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
Ke zprávě výjimky se dostaneme přes vlastnost Message.
Všimněte si také, že zprávě nastavujeme ikonku vykřičníčku. V metodě
již neřešíme žádnou logiku a je díky tomu poměrně krátká.
V tomto formuláři jsme skončili. Přesuneme se zpět do
PrehledForm, tentokrát do grafické části a naklikneme
tlačítka pridatButton a odebratButton.
private void pridatButton_Click(object sender, EventArgs e) { OsobaForm osobaForm = new OsobaForm(spravceOsob); osobaForm.ShowDialog(); }
V obslužné metodě tlačítka pridejButton vytvoříme novou
instanci formuláře OsobaForm, které předáme místního
správce osob. Na instanci následně zavoláme metodu
ShowDialog(). Ta zobrazí nový formulář (stejně jako metoda
Show()) a k tomu ještě zablokuje zbytek aplikace, který se
zaktivní až v případě, kdy se dialog zavře. Výsledkem je, že se s
hlavním formulářem nedá pracovat dokud dialog nepotvrdíme či neukončíme.
U dialogu (rozumějte pomocného formuláře, který slouží nejčastěji k
zadání dat) se toto většinou dělá. I když nám by v podstatě nevadilo,
kdyby uživatel během zadávání nové osoby aplikaci používal a otevřel
třeba další dialog k zadávání.
Obslužná metoda tlačítka odebratButton bude vypadat
takto:
private void odebratButton_Click(object sender, EventArgs e) { if (osobyListBox.SelectedItem != null) { spravceOsob.Odeber((Osoba)osobyListBox.SelectedItem); } }
Důležitá je podmínka, která zjišťuje, zda je v ListBoxu
vybraná nějaká položka. Jak vidíte, k vybrané položce se dostaneme přes
vlastnost SelectedItem. Položku následně přetypujeme na
Osoba, jelikož je typu object (to aby byl
ListBox univerzální). Tuto osobu předáme metodě
Odeber() na správci, která dále vykoná fyzické odebrání z
listu.
Aplikaci si nyní můžete vyzkoušet, již půjde přidávat a odebírat
osoby. Přidané osoby se ihned objeví v ListBoxu díky
bindingům. ListBox vždy zobrazuje to, co vrací metoda
ToString() objektu. U osob tedy zobrazuje jejich jméno. Pokud
bychom chtěli zobrazit jinou vlastnost, zadáme její název do vlastnosti
DisplayMember na ListBoxu (např. pro zobrazení
narozenin tedy Narozeniny). Podobně fungují samozřejmě i
další ovládací prvky, např. ComboBox.

Nejbližší narozeniny
Do třídy hlavního formuláře si přidáme pomocnou privátní metodu
ObnovNejblizsi(), která obnoví popisek s nejbližšími
narozeninami.
private void ObnovNejblizsi() { if (spravceOsob.Osoby.Count > 0) { Osoba nejblizsi = spravceOsob.NajdiNejblizsi(); int vek = nejblizsi.SpoctiVek(); if (DateTime.Today != nejblizsi.Narozeniny) vek++; nejblizsiLabel.Text = nejblizsi.Jmeno + " (" + vek + " let) za " + nejblizsi.ZbyvaDni() + " dní"; } else nejblizsiLabel.Text = "Žádné osoby v seznamu"; }
V případě, že jsou ve správci osob nějaké osoby, najdeme osobu s nejbližšími narozeninami. Získáme si věk této osoby a pokud nemá narozeniny právě dnes, přičteme k němu jedničku, aby se jednalo vždy o budoucí věk osoby. Do příslušného labelu poté poskládáme jméno osoby, do závorky její budoucí věk a kolik dní do narozenin zbývá.
V případě, že ve správci žádné osoby nemáme, zobrazíme o tom v labelu zprávu uživateli.
Metodu zavoláme na konci konstruktoru formuláře a také po přidání a odebrání osoby (na konci obslužných metod tlačítek, ale samozřejmě stále v podmínkách).
Detaily osoby
Shází nám již jen zobrazovat detaily vybrané osoby. Naklikneme si
ListBox, čímž nám Visual Studio vygeneruje obslužnou metodu
události SelectedIndexChanged (změna vybrané položky). Zde
musíme opět zkontrolovat, zda je nějaká položka (osoba) vybraná. Pokud
ano, načteme si jí a její vlastnosti zobrazíme v příslušných labelech a
MonthCalendar nastavíme na její datum narození.
if (osobyListBox.SelectedItem != null) { Osoba vybrana = (Osoba)osobyListBox.SelectedItem; narozeninyLabel.Text = vybrana.Narozeniny.ToLongDateString(); vekLabel.Text = vybrana.SpoctiVek().ToString(); narozenMonthCalendar.SelectionStart = vybrana.Narozeniny; }
Aplikaci si můžete vyzkoušet.

V příští lekci, Upomínač narozenin - Ukládání dat a závěr, dokončíme ukládání a načítání dat z/do souboru. Dosavadní zdrojové kódy jsou vám jako vždy k dispozici níže. Pokud jste se někde zasekli, najděte si chybu.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 1542x (346.33 kB)
Aplikace je včetně zdrojových kódů v jazyce C#


David se informační technologie naučil na