7. diel - PRIPOMIENKOVÉ narodenín v C # .NET WPF - Logická vrstva
V minulej lekcii, PRIPOMIENKOVÉ narodenín v C # .NET WPF - Návrh okien , sme navrhli kompletne formuláre pre našu aplikáciu. V tomto C# .NET tutoriálu sa budeme zaoberať návrhom logické vrstvy, teda tried, ktoré obsahujú logiku aplikácie.
Osoba
V našej aplikácii budú celkom iste figurovať osoby, vytvorme im teda
triedu. Pred triedu nezabudnite dať modifikátor public.
Vlastnosti
Osoba bude mať 4 vlastnosti:
Jmeno- meno typustringNarozeniny- narodeniny typuDateTimeVek- vek typuintZbyvaDni- zostávajúci počet dní do najbližších narodenín typuint
Prvé dve vlastnosti sú jednoduché:
public string Jmeno { get; set; } public DateTime Narozeniny { get; set; }
Tieto vlastnosti nastavíme pomocou parametrického konstruktoru. Trieda vyzerá zatiaľ takto:
public class Osoba { public string Jmeno { get; set; } public DateTime Narozeniny { get; set; } public Osoba(string jmeno, DateTime narozeniny) { Jmeno = jmeno; Narozeniny = narozeniny; } }
Ďalšie dve vlastnosti nebudú obyčajnou premennú, ale budú obsahovať ďalšie logiku. Takéto vlastnosti je potom možné pomocou binding jednoducho zobrazovať na formulári.
Vek
Vlastnosť vypočíta a vráti aktuálne vek osoby v celých rokoch.
Výpočet bohužiaľ nie je len o tom odpočítať dva dátumy, pretože
TimeSpan nevie zistiť počet rokov, iba počet dní. Výpočet
veku teda vykonáme nasledujúcim spôsobom:
- Získame si aktuálny dátum (bez času) pomocou
DateTime.Today. - Vek spočítame ako rozdiel rokov v aktuálnom dátume a dátume narodenín. Asi je vám jasné, že tento vek nie je presný. Ak sme sa narodili 1.2.1990 a je 1.1.2010, nie je nám 20 rokov, ale len 19. Z toho dôvodu vykonáme korekciu.
- V prípade, že je aktuálny dátum menšia (skôr) ako dátum narodenia po pridaní nami vypočítaných rokov, nastal vyššie uvedený prípad a my vek o rok znížime.
- Hotový vek vrátime.
Kód vlastnosti bude nasledujúci:
public int Vek { get { DateTime dnes = DateTime.Today; int vek = dnes.Year - Narozeniny.Year; if (dnes < Narozeniny.AddYears(vek)) vek--; return vek; } }
ZbyvaDni
Vlastnosť nám vráti koľko dní zostáva do narodenín osoby. To zistíme nasledujúcim spôsobom:
- Získame si aktuálny dátum (bez času).
- Získame dátum ďalších narodenín pripočítaním veku + 1 k dátumu narodenia.
- Dáta odčítame a celkový rozdiel v dňoch vrátime. Keďže je rozdiel
typu
double, musíme ho skonvertovať naint.
public int ZbyvaDni { get { DateTime dnes = DateTime.Today; DateTime dalsiNarozeniny = Narozeniny.AddYears(Vek + 1); TimeSpan rozdil = dalsiNarozeniny - DateTime.Today; return Convert.ToInt32(rozdil.TotalDays); } }
ToString ()
Keďže budeme osoby vypisovať, prepíšeme triede ešte metódu
ToString() tak, aby vracala meno osoby:
public override string ToString() { return Jmeno; }
Správca osôb
Ďalšie logickú komponentom aplikácia bude správca osôb. Trieda sa bude starať o osoby, bude ich vedieť pridávať, odoberať a ich zoznam ukladať do súboru a opätovne načítať. Konečne bude vedieť medzi osobami vyhľadať tú, ktorá má najbližšie narodeniny.
Pridajte si k projektu teda triedu SpravceOsob a urobte ju
verejnú.
Vlastnosti a atribúty
Správca osôb bude disponovať tromi verejnými vlastnosťami.
Prvý je zoznam osôb typu ObservableCollection. S touto
kolekciou sme sa v kurze ešte nestretli. Jedná sa o múdrejší
List, ktorý na sebe vie vyvolať udalosť zmeny v prípade, že sa
zmení jeho obsah. Vďaka tomuto mechanizmu sa automaticky obnoví všetky prvky
na formulári, ktoré majú nastavený ako zdroj údajov práve túto
ObservableCollection. Asi si dokážete predstaviť, že obnovovať
ručne desiatky formulárových prvkov v prípade zmeny môže byť veľmi
neprehľadné. Akonáhle v našej aplikácii pridáme novú osobu, bude ihneď
vidieť v zozname osôb bez toho aby sme ho obnovovali, obnoví sa sám.
ObservableCollection() inicializujeme v konstruktoru.
Ak by sme chceli implementovať aj editáciu osôb, musela by trieda
Osoba implementovať rozhranie INotifyPropertyChanged.
Akákoľvek zmena (napr. Mená) by sa potom automaticky prejavila vo všetkých
prvkoch všetkých formulárov, kde osoba figuruje. Týmto sa však pre
zjednodušenie zaoberať nebudeme.
Trieda zatiaľ vyzerá takto:
public class SpravceOsob { public ObservableCollection<Osoba> Osoby { get; set; } public SpravceOsob() { Osoby = new ObservableCollection<Osoba>(); } }
Ďalšími vlastnosťami sú:
DnesniDatum, ktorá vráti dnešný dátum.- A
NejblizsiOsoba, ktorá vráti osobu s najbližšími narodeninami.
Ich kód:
public Osoba NejblizsiOsoba { get; set; } public DateTime DnesniDatum { get { return DateTime.Now; } }
Metódy
Okrem pridávanie a odoberanie bude trieda vedieť aj nájsť osobu s najbližšími narodeninami. Ukladanie a načítanie osôb do / zo súboru necháme na neskôr.
NajdiNejblizsi ()
Metóda nájde a uloží osobu, ktorá má najbližšie narodeniny. Na
vyhľadanie osoby v zozname použijeme LINQ
metódu OrderBy(), ktorá osoby usporiada podľa toho, koľko dní
zostáva do ich narodenín. Výsledok uložíme do kolekcie, ktorej typ
neuvedieme a použijeme namiesto toho kľúčové slovo var, ako je
v LINQ zvykom. Následne vrátime prvú osobu. Metódu by sme mali volať len
vtedy, keď sú v zozname nejakej osoby. Bude tiež privátne, pretože ju
budeme volať len vnútri triedy. Hoci by z kódu malo byť jasné, čo metóda
robí, môžete sa samozrejme pozrieť na tutoriály v sekcii Kolekcia a LINQ v C# .NET, kde je technológia
LINQ detailne popísaná.
private void NajdiNejblizsi() { var serazeneOsoby = Osoby.OrderBy(o => o.ZbyvaDni); if (serazeneOsoby.Count() > 0) NejblizsiOsoba = serazeneOsoby.First(); else NejblizsiOsoba = null; }
Pridajme ()
Metóda pridá novú osobu do ObservableCollection. Keďže
osobu budeme pridávať formulárom, hodí sa nám, aby metóda brala v
parametroch vlastnosti osoby a na ich základe vytvorila novú inštanciu. Z
dátumu narodenia uložíme iba časť s dátumom, teda bez času.
Pred pridaním skontrolujeme, či meno nie je príliš krátke alebo nie je zadaný dátum v budúcnosti. Ak nejaká z týchto situácií nastane, vyvoláme výnimku. Práve výnimky sú jediným správnym spôsobom, ako s chybami v objektových aplikáciách pracovať.
Výnimky sú detailnejšie popísané v sekcii Práca so súbormi v C# .NET. Ak ste sa s nimi ešte
nestretli, bude vám stačiť vedieť, že výnimka sa vyvolá pomocou
kľúčového slova throw, za ktorým nasleduje inštancie
výnimky. Výnimiek máme niekoľko typov vrátane možnosti vytvoriť si
vlastný. V našom prípade sa nám hodí ArgumentException (chyba
v argumentu). Do konstruktoru výnimky zadávame text chyby. Akonáhle je
výnimka vyvolaná, metóda už ďalej nepokračuje. Ako na chybu reagovať si
ukážeme až budeme metódu volať z formulára.
Pri zadávaní dáta ovládacím prvkom DatePicker dostaneme
dátum ako typ DateTime?. Ak ste dočítali objektový kurz C# až do konca, viete, že otáznik
značí tzv. Nullovatelný typ. To je akési rozšírenie hodnotového
dátového typu o hodnotu null, ktorú hodnotový typ bežne
obsahovať nemôže. Pokiaľ je v dátume null, znamená to, že
nebolo zadané a vyhodíme tiež výnimku. K hodnote nullovatelného typu
pristupuje cez vlastnosť Value.
public void Pridej(string jmeno, DateTime? datumNarozeni) { if (jmeno.Length < 3) throw new ArgumentException("Jméno je příliš krátké"); if (datumNarozeni == null) throw new ArgumentException("Nebylo zadané datum narození"); if (datumNarozeni.Value.Date > DateTime.Today) throw new ArgumentException("Datum narození nesmí být v budoucnosti"); Osoba osoba = new Osoba(jmeno, datumNarozeni.Value.Date); Osoby.Add(osoba); NajdiNejblizsi(); }
Na konci metódy obnovíme najbližší osobu, pretože to môže byť práve tá pridaná.
Odober ()
Metóda odoberie osobu z ObservableCollection. Pretože vždy
budeme chcieť odoberať už hotovú osobu, berie metóda v parametri práve
tú. Po odobratí opäť obnovíme najbližšej osobu.
public void Odeber(Osoba osoba) { Osoby.Remove(osoba); NajdiNejblizsi(); }
Pokračovať budeme v lekcii, PRIPOMIENKOVÉ narodenín v C # .NET WPF - Prepojenie vrstiev , kedy aplikáciu sprevádzkujeme. Doterajšie zdrojový kód je k stiahnutiu nižšie.

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