Se ci ricordiamo bene, la UI della nostra applicazione
Age è piuttosta semplice e spartano. Nel post [MCAD.15] avevamo implementato le funzioni di stampa e
lo screenshot mostra il MainMenu aperto. Le funzioni
disponibili fino a questo momento sono le seguenti:
- Imposta Pagina (handler mnuPageSetup_Click)
- Anteprima di Stampa (handler mnuPrintPreview_Click)
- Stampa (handler mnuPrint_Click)
- Esci (handler mnuExit_Click)
Vi rimando al post [MCAD.15] per tutti i dettagli sull'implementazione degli
handler elencati sopra. Quello che vogliamo fare oggi è integrare nuove voci
al componente MainMenu per far posto alle nuove features che implementeremo. Qui sotto riporto uno screenshot
dell'applicazione.
Abbiamo aggiunto le seguenti voci:
- Nuovo (handler mnuNew_Click)
Svuota la ListBox per cominciare
un nuovo elenco di compleanni
- Carica (handler mnuCarica_Click)
Carica un file XML
precedentemente salvato
- Salva con nome (handler mnuSave_Click)
Salva l'elenco dei compleanni
contenuti nella ListBox su un file XML
- Importa (handler mnuImport_Click)
Crea un nuovo elenco di
compleanni unendo l'elenco contenuto nella ListBox con un altro elenco preso
da file XML salvato precedentemente
Creazione di un nuovo elenco
Questo è semplice! L'handler non fa altro che chiamare il
metodo Clear della collection Items della
classe ListBox. Il codice, semplicissimo, è il seguente:
private void mnuNew_Click(object sender, System.EventArgs e)
{
// Svuoto la ListBox
this.lstResults.Items.Clear();
}
Avremmo potuto mettere una conferma, oppure chiamare il
.Clear() solo quando Items.Count > 0: per
semplicità, svuoto ogni volta senza troppe complicazioni.
Che ne dite se
vediamo qualcosa di più interessante?
Salvataggio dei nostri compleanni in un file
XML
Innanzitutto ricordiamoci la function
getSaveTable() che abbiamo creato nel post [MCAD.19] di ieri. Abbiamo detto che questa function
ritorna una DataTable contenente schema + dati: fate riferimento al post
precedente per tutti i dettagli implementativi (creazione della DataTable
con le DataColumn, creazione di tante DataRow per il popolamento della
DataTable, etc.).
Quello che vogliamo fare oggi è produrre un DataSet che è la
classe primaria per lavorare con ADO.NET. Ripetiamolo: un DataSet è l'immagine
in memoria di un database (o meglio, volendo solo di una parte di database) con
tutte le tabelle di cui è composto. Vediamo un po' il codice. Il click
sull'oggetto mnuSave viene gestito dall'handler
mnuSave_Click, il cui codice è riportato sotto. Vedremo di
commentarlo e di capire un po' di cose sul famigerato DataSet.
private void mnuSave_Click(object sender, System.EventArgs e)
{
// Creo un'istanza SaveFileDialog
SaveFileDialog dlgSaving = new SaveFileDialog();
// Imposto alcune property per facilitare l'usabilità
dlgSaving.CheckPathExists = true;
dlgSaving.AddExtension = true;
dlgSaving.OverwritePrompt = true;
dlgSaving.Filter = "Files XML|*.xml";
if (dlgSaving.ShowDialog() == DialogResult.OK)
{
// creo un dataset (inizialmente vuoto)
DataSet dsBirthdays = new DataSet();
dsBirthdays.DataSetName = "Birthdays";
// al dataset appena creato aggiungo la tabella generata
// dalla function getSaveTable()
dsBirthdays.Tables.Add(this.getSaveTable(true));
// Salvo il file XML
dsBirthdays.WriteXml(dlgSaving.FileName, XmlWriteMode.WriteSchema);
// Dopo il salvataggio, libero la memoria
dsBirthdays.Dispose();
}
dlgSaving.Dispose();
}
In breve: facciamo scegliere all'utente il file su cui salvare
(component SaveFileDialog),
creiamo un Dataset dsBirthdays e tramite la property
Tables di questo DataSet aggiungiamo la DataTable generata
dalla nostra function. Chiamiamo il metodo WriteXML del DataSet
per creare il file XML vero e proprio. Poi, giusto per pulizia di
codice, chiamiamo il metodo Dispose per liberare eventuali
risorse. Basta, nulla di più. Avete visto quante linee di codice servono per
fare tutto? Beh, direi che .NET ci dà veramente una mano, vero? Vediamo di dare
qualche dettaglio in più.
Innanzitutto, abbiamo la classe
SaveFileDialog. Questa classe apre la finestra standard offerta
dall'OS per il salvataggio dei files. Usiamo le seguenti property:
- CheckPathExists
(controllo che il path selezionato dall'utente esista)
- AddExtension
(se l'utente non aggiunge l'estensione al file, lo fa automaticamente il
framework)
- OverwritePrompt
(se l'utente seleziona un file esistente, chiede conferma prima di
sovrascrivere)
- Filter (filtro per, appunto, filtrare solo un determinato
tipo di files: nel nostro caso, *.xml)
Del DataSet dsBirthdays, invece, abbiamo usato:
- DataSetName
(una stringa che ci sarà utile per leggere meglio il file XML)
- Tables (collection di DataTable, che eredita direttamente
dalla classe Collection del framework)
- WriteXML (metodo per scrivere su disco un file XML.
Dispone di 8 overloading per scrivere il file usando XMLWriter, TextWriter o
stream di altro tipo)
Se avete scritto il codice correttamente, provate a compilare e ad eseguire
il progetto. Inserite qualche compleanno: il vostro, i vostri genitori, figli o
chi volete voi. Aprite il menù, cliccate su Salva con nome: apparirà la finestra di dialogo
per la scelta del file. Salvate sul desktop con il nome che volete. Aprite il
file XML con Notepad, o con qualsiasi editor abbiate. Il file contiene sia lo
schema XML, sia i dati.