5. diel - PRIPOMIENKOVÉ narodenín - Prepojenie prezentačnej a logické vrstvy
V minulej lekcii, PRIPOMIENKOVÉ narodenín - Logická vrstva , sme naprogramovali väčšinu logické vrstvy aplikácie pre upomínania narodenín. Dnes v C# .NET tutoriálu aplikáciu sprevádzkujeme.
Oddelenie prezentácie a logiky
Teraz máme dokončenú tzv. Prezentačné časť aplikácie (formulára) a logickú časť (triedy). Tieto 2 vrstvy sa v aplikácii striktne oddeľujú, pretože inak je kód veľmi neprehľadný. Nikdy by ste nemali vykonávať výpočty, zápisy do súborov, databázy a podobné veci priamo v kóde formulára! Vždy si vytvoríme triedu, ktorá poskytuje príslušné metódy a túto triedu z formulára iba používame. Logika zostane v triede. Trieda by naopak vôbec nemala vedieť o formulári. Nemala by teda napr. Zobrazovať chybové hlášky, ale iba vyvolávať v prípade chyby výnimky. Je potom na formulári, aby užívateľovi chybu zobrazil. Práve formulár je tá časť aplikácie, ktorá s užívateľom komunikuje. Žiadna iná to nerobí.
Ak vás napadlo, že naše jednoduchá kalkulačka, ktorú sme vytvorili v prvých lekciách kurze, bola návrhové zle, máte pravdu. Z dôvodu jednoduchosti sme napísali výpočty rovno do obslužnej metódy tlačidla. Správne by sme mali mať nejakú triedu, ktorá by výsledky počítala a tú by sme z formulára iba volali.
Dnes si teda ukážeme, ako sa to robí správne.
Prepojenie prezentácie a logiky
Prejdeme do zdrojového kódu formulára PrehledForm
a triede
pridáme privátne atribút typu SpravceOsob
, v ktorom rovno
vytvoríme inštanciu správcu:
private SpravceOsob spravceOsob = new SpravceOsob();
Inštancie správcu sa vytvorí pri vytvorení formulára a formulár s ňou ďalej bude komunikovať a tak vykonávať úkony, ktoré si želá užívateľ.
V konstruktoru formuláre nastavíme dnesLabel
na aktuálny
dátum a ListBox
u nastavíme vlastnosť DataSource
na
BingList
Osoby
na správcovi osôb. Tým napojíme
ListBox
na BindingList
, odteraz bude zobrazovať jeho
obsah a ak sa do listu niečo pridá, prejaví sa to aj v ListBox
u.
public PrehledForm()
{
InitializeComponent();
dnesLabel.Text = DateTime.Now.ToLongDateString();
osobyListBox.DataSource = spravceOsob.Osoby;
}
Pridávanie a mazanie osôb
Aby sme niečo konečne tiež videli, prejdeme k pridávanie osôb. Najprv
prejdeme do kódu formulára OsobaForm
, kde si rovnako ako v
predchádzajúcom formulári pripravíme správcu osôb ako privátne atribút.
Keby sme tu aj vytvorili jeho inštanciu, nebolo by nám to moc platné,
pretože osoby by boli načítané v správcovi v hlavnom formulári. A
načítať ich znovu by bolo neefektívne. Necháme si teda hotového a
načítaného správcu odovzdať konštruktory a uložíme ho do pripravenej
premennej:
private SpravceOsob spravceOsob; public OsobaForm(SpravceOsob spravceOsob) { InitializeComponent(); this.spravceOsob = spravceOsob; }
Teraz naklikne tlačidlo OK a do správcu pridáme osobu pomocou hodnôt,
ktoré užívateľ do jednotlivých prvkov zadal. K hodnote v
TextBox
u pristúpime pomocou vlastnosti Text
, k
hodnote v DateTimePickeru
pomocou vlastnosti
Value
.
Určite si spomínate, že metóda Pridej()
vyvolá výnimku v
prípade príliš krátkeho mena alebo dáta v budúcnosti. Preto kód s
pridaním vložíme do bloku try
, za ktorým bude nasledovať blok
catch
. Ak výnimka v bloku try
nastane, program sa
ihneď presunie do bloku catch
, kde pomocou MessageBox
u zobrazí chybovú hlášku. Ak by sme výnimku takto neošetrili, spôsobila
by pád aplikácie.
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); } }
K správe výnimky sa dostaneme cez vlastnosť Message
.
Všimnite si tiež, že správe nastavujeme ikonku vykřičníčku. V metóde
už neriešime žiadnu logiku a je vďaka tomu pomerne krátka.
V tomto formulári sme skončili. Presunieme sa späť do
PrehledForm
, tentoraz do grafickej časti a naklikne tlačidlá
pridatButton
a odebratButton
.
private void pridatButton_Click(object sender, EventArgs e) { OsobaForm osobaForm = new OsobaForm(spravceOsob); osobaForm.ShowDialog(); }
V obslužné metóde tlačidla pridejButton
vytvoríme novú
inštanciu formulára OsobaForm
, ktoré odovzdáme miestneho
správcu osôb. Na inštanciu následne zavoláme metódu
ShowDialog()
. Tá zobrazí nový formulár (rovnako ako metóda
Show()
) ak tomu ešte zablokuje zvyšok aplikácie, ktorý sa
zaktivní až v prípade, keď sa dialóg zatvorí. Výsledkom je, že sa s
hlavným formulárom nedá pracovať kým dialóg nepotvrdíme či neukončíme.
U dialógu (rozumejte pomocného formulára, ktorý slúži najčastejšie na
zadanie údajov) sa toto väčšinou robí. Aj keď nám by v podstate nevadilo,
keby užívateľ počas zadávania novej osoby aplikáciu používal a otvoril
potrebné ďalšie dialóg na zadávanie.
Obslužná metóda tlačidla odebratButton
bude vyzerať
takto:
private void odebratButton_Click(object sender, EventArgs e) { if (osobyListBox.SelectedItem != null) { spravceOsob.Odeber((Osoba)osobyListBox.SelectedItem); } }
Dôležitá je podmienka, ktorá zisťuje, či je v ListBox
u
vybraná nejaká položka. Ako vidíte, k vybranej položke sa dostaneme cez
vlastnosť SelectedItem
. Položku následne přetypujeme na
Osoba
, pretože je typu object
(to aby bol
ListBox
univerzálne). Túto osobu odovzdáme metóde
Odeber()
na správcovi, ktorá ďalej vykoná fyzické odobratie z
listu.
Aplikáciu si teraz môžete vyskúšať, už pôjde pridávať a odoberať
osoby. Pridanej osoby sa ihneď objaví v ListBox
u vďaka
bindingům. ListBox
vždy zobrazuje to, čo vracia metóda
ToString()
objektu. U osôb teda zobrazuje ich meno. Ak by sme
chceli zobraziť inú vlastnosť, zadáme jej názov do vlastnosti
DisplayMember
na ListBox
u (napr. Pre zobrazenie
narodenín teda Narozeniny
). Podobne fungujú samozrejme aj
ďalšie ovládacie prvky, napr. ComboBox
.
Najbližšej narodeniny
Do triedy hlavného formulára si pridáme pomocnú privátne metódu
ObnovNejblizsi()
, ktorá obnoví popisok s najbližšími
narodeninami.
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 prípade, že sú v správcovi osôb nejakej osoby, nájdeme osobu s najbližšími narodeninami. Získame si vek tejto osoby a pokiaľ nemá narodeniny práve dnes, pripočítame k nemu jedničku, aby išlo vždy o budúcej vek osoby. Do príslušného labelu potom poskladáme meno osoby, do zátvorky jej budúce vek a koľko dní do narodenín zostáva.
V prípade, že v správcovi žiadne osoby nemáme, zobrazíme o tom v labelu správu užívateľovi.
Metódu zavoláme na konci konstruktoru formuláre a tiež po pridaní a odobratie osoby (na konci obslužných metód tlačidiel, ale samozrejme stále v podmienkach).
Detaily osoby
Shaza nám už len zobrazovať detaily vybranej osoby. Naklikne si
ListBox
, čím nám Visual Studio vygeneruje obslužnú metódu
udalosti SelectedIndexChanged
(zmena vybranej položky). Tu musíme
opäť skontrolovať, či je nejaká položka (osoba) vybraná. Ak áno,
načítame si ju a jej vlastnosti zobrazíme v príslušných labeloch a
MonthCalendar
nastavíme na jej dátum narodenia.
if (osobyListBox.SelectedItem != null) { Osoba vybrana = (Osoba)osobyListBox.SelectedItem; narozeninyLabel.Text = vybrana.Narozeniny.ToLongDateString(); vekLabel.Text = vybrana.SpoctiVek().ToString(); narozenMonthCalendar.SelectionStart = vybrana.Narozeniny; }
Aplikáciu si môžete vyskúšať.
V budúcej lekcii, PRIPOMIENKOVÉ narodenín - Ukladanie dát a záver , dokončíme ukladanie a načítanie dát z / do súboru. Doterajšie zdrojové kódy sú vám ako vždy k dispozícii nižšie. Ak ste sa niekde zasekli, nájdite si chybu.
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é 1532x (346.33 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#