Lekce 5 - Uložení objektů do CSV v C# část 2
V minulé lekci, Uložení objektů do CSV v C#, jsme načali databázi uživatelů pomocí CSV souborů.
Nyní aplikaci dokončíme a doladíme.
Načtení uživatelů z CSV souboru
Uložení nám funguje, zbývá umět data opětovně načíst. Soubor budeme
číst řádek po řádku, každý řádek rozdělíme metodou
Split()
a následně do kolekce přidáme objekt s příslušnými
hodnotami. Před načtením si kolekci vyprázdníme, aby v ní nebyli i
uživatelé načtení někdy dříve (kdyby se aplikace někdy
rozšiřovala).
public void Nacti() { uzivatele.Clear(); // Otevře soubor pro čtení using (StreamReader sr = new StreamReader(soubor)) { string s; // čte řádek po řádku while ((s = sr.ReadLine()) != null) { // rozdělí string řádku podle středníků string[] rozdeleno = s.Split(';'); string jmeno = rozdeleno[0]; int vek = int.Parse(rozdeleno[1]); DateTime registrovan = DateTime.Parse(rozdeleno[2]); // přidá uživatele s danými hodnotami PridejUzivatele(jmeno, vek, registrovan); } } }
Třída databáze je tedy kompletní. Nyní se zaměříme na formulářovou část.
Prezentační vrstva aplikace
Jako první si připravíme nové formulářové prvky (ovládací prvky z
ToolBoxu). Přidáme tlačítko načíst, dále ListBox
listUzivatelu
, u kterého nastavíme Sorted
na
true
. Dále TextBox
na jméno nového uživatele,
NumericUpDown
na jeho věk a DateTimePicker
na datum
registrace. K ovládacím prvkům přidáme nějaké labely. Tyto prvky můžeme
seskupit do GroupBox
u. V dalším GroupBox
u budou 3
labely na detail uživatele, ty pojmenujeme labelJmena
,
labelVeku
a labelRegistrace
. Další 3 labely
přidáme jako jejich popisek. Nakonec přidáme tlačítko k přidání
uživatele a celou aplikaci můžeme oživit PictureBox
em. Pokud to
bylo moc rychlé, nezoufejte, tady je obrázek výsledného formuláře:
V reálu by bylo přidání uživatelů pravděpodobně přítomno v dalším formuláři, který by se zobrazoval jako dialog, ale nám to bude v tutoriálu stačit takto.
Z tlačítka Uložit odstraníme vytvoření testovacích uživatelů.
Samotné uložení nyní vložíme do try
-catch
bloku.
Víme totiž, že finally
(tedy using
blok v naší
databázi) výjimky nepohlcuje, což také chceme a budeme na ně reagovat ve
formulářové části, kam reakce logicky patří. Upozornění na chybu, tedy
komunikace s uživatelem, přímo ve třídě Databaze
by bylo
špatně. Po zachycení výjimky zobrazíme MessageBox
s chybou.
Metoda tlačítka bude tedy vypadat takto:
try { databaze.Uloz(); } catch { MessageBox.Show("Databázi se nepodařilo uložit, zkontrolujte přístupová práva k souboru.", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error); }
Obdobně naklikneme metodu tlačítka Načíst, pouze po načtení databáze
vložíme objekty do ListBox
u. Ten předtím vymažeme, aby nám
tam nezůstávali uživatelé z předešlého načtení. V reálu by se
načtení vykonalo asi automaticky po spuštění aplikace a uložení po
ukončení, pro názornost si to však ponecháme na tlačítkách. Metoda
tlačítka Načíst tedy vypadá takto:
try { databaze.Nacti(); listUzivatelu.Items.Clear(); listUzivatelu.Items.AddRange(databaze.VratVsechny()); } catch { MessageBox.Show("Databázi se nepodařilo načíst, soubor zřejmě neexisituje.", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error); }
Nyní zpracujeme kliknutí na listUzivatelu
, které provede
zobrazení detailu uživatele do připravených labelů:
if (listUzivatelu.SelectedItem != null) { Uzivatel u = (Uzivatel)listUzivatelu.SelectedItem; labelJmena.Text = u.Jmeno; labelVeku.Text = u.Vek.ToString(); labelRegistrace.Text = u.Registrovan.ToShortDateString(); }
Kód jsme opodmínkovali pro případ, že by nebyl žádný uživatel
vybrán (list by byl prázdný), za řeč stojí přetypování označené
položky na typ Uzivatel
, jelikož ListBox
není
generická kolekce a C# tedy neví, jakého je item typu. Můžete si
vyzkoušet, že vše funguje.
Poslední tlačítko bez metody je Přidání nového uživatele. Rozklikneme
ho tedy, vložení bude velmi jednoduché, prvek ovšem musíme přidat jak do
databáze, tak do listUzivatelu
. U složitějších aplikací
bychom použili tzv. databinding, ale nás by to nyní jen pletlo, zájemce
odkáži na kurz o okenních aplikacích.
private void tlacitkoPridat_Click(object sender, EventArgs e) { string jmeno = jmenoTextBox.Text; int vek = Convert.ToInt32(vekNumericUpDown.Value); DateTime registrovan = registrovanDateTimePicker.Value; databaze.PridejUzivatele(jmeno, vek, registrovan); listUzivatelu.Items.Add(new Uzivatel(jmeno, vek, registrovan)); }
Zkusíme přidat nového uživatele:
Podobně bychom si mohli napsat i mazání uživatelů, ale to již nechám
na vás. Zbývá nám ještě ošetřit cestu k souboru, aby vedla do složky
AppData, nikoli do složky s programem. To umíme z tutoriálu Úvod do práce
se soubory . Také bychom mohli vymazat text labelů při startu programu.
Obojí vykonáme v konstruktoru formuláře, do using
si přidáme
System.IO
.
public Form1() { InitializeComponent(); // vyprázdnění labelů detailu uživatele labelJmena.Text = ""; labelVeku.Text = ""; labelRegistrace.Text = ""; // vytvoření složky aplikace v AppData string cesta = ""; try { cesta = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DatabazeUzivatelu"); if (!Directory.Exists(cesta)) Directory.CreateDirectory(cesta); } catch { MessageBox.Show("Nepodařilo se vytvořit složku " + cesta + ", zkontrolujte prosím svá oprávnění.", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error); } // vytvoření databáze databaze = new Databaze(Path.Combine(cesta, "uzivatele.csv")); }
A je to
Naše aplikace je téměř hotová, ještě se zamyslíme nad tím, co se
stane, když někdo do jména vloží středník. Aplikace se rozbije. Proto
budeme v metodě Uloz()
středníky ze jména odstraňovat.
Kdybychom dělali aplikaci, kde bychom je potřebovali (což se nestává
příliš často), můžeme vybrat jiný zástupný znak. Pokud bychom chtěli
být dokonalí, vložíme takovou hodnotu se středníkem do uvozovek. Poté se
však již nejedná o jednoduché CSV a metoda Split()
nám
přestane stačit, zájemce odkáži na třídu
Microsoft.VisualBasic.FileIO.TextFieldParser
. Dále by se to
samozřejmě dalo řešit jiným formátem. My si tedy středníky pouze
odstraňme, přesněji je nahradíme mezerami změnou jediného řádku v
metodě Uloz()
:
string[] hodnoty = { u.Jmeno.Replace(';',' '), u.Vek.ToString(), u.Registrovan.ToShortDateString() };
A jsme hotoví. Pokud vám něco nešlo úplně hladce, hotový projekt máte jako vždy v příloze i se zdrojovým kódem.
V následujícím kvízu, Kvíz - Výjimky, text. soubory, formát CSV v C# .NET, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
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 1326x (82.14 kB)
Aplikace je včetně zdrojových kódů v jazyce C#