Oggi sono in modalità “inventario” sul codice delle mie librerie standard, ovvero sto passando al framework 4.0 e facendo ciò mi dedico alle “pulizie di primavera” eliminando cose ormai obsolete, usando funzionalità un po’ più evolute su vecchie funzioni, e già che ci sono, apportando al mio generatore di codice che dal 2006 produce automaticamente le classi per la manipolazione dei dati che utilizzo con i miei database alcuni aggiornamenti.
Uno di questi è l’aggiunta di alcuni eventi che saranno scatenati dalle classi quando vengono effettuate le funzioni di aggiornamento. Due di questi sono l’evento RowAdded e l’evento RowDeleted, in entrambi i casi, se decidiamo di gestire l’evento scatenato, potrebbe esserci utile avere delle informazioni sui dati aggiunti o cancellati. Per questo motivo, ho deciso di inserire negli argomenti dell’evento, l’intera DataRow aggiunta o cancellata.
Passare una DataRow appena aggiunta ad una DataTable è semplice, mentre invece passare una DataRow cancellata non è proprio una cosa immediata. Per capire come fare ho creato un progettino di test, il cui codice riporto in questo post con qualche commento.
La form di esempio è la seguente:
Sulla form ci sono 3 button – Carica, Test Aggiunta, Test cancellazione. c’è anche una textbox con l’opzione Multiline a True e la scrollbar verticale visibile.
Di seguito, vediamo il codice dietro alla form:
DataTable mDt; private const string FLD_ID = "ID"; private const string FLD_Description = "Description"; private const string FLD_Date = "Date"; private const string FLD_Price = "Price"; public Form1() { InitializeComponent(); mDt = new DataTable("Tbtest"); DataColumn col = new DataColumn(FLD_ID, typeof(int)); col.AutoIncrement = true; col.AutoIncrementSeed = 1; col.AutoIncrementStep = 1; mDt.Columns.Add(col); col = new DataColumn(FLD_Description, typeof(string)); mDt.Columns.Add(col); col = new DataColumn(FLD_Date, typeof(DateTime)); mDt.Columns.Add(col); col = new DataColumn(FLD_Price, typeof(Decimal)); mDt.Columns.Add(col); }
Nel costruttore, Genero la mia datatable e vi aggiungo le colonne, per comodità i nomi delle colonne sono delle costanti.
private void btnCarica_Click(object sender, EventArgs e) { mDt.Rows.Clear(); DataRow row = mDt.NewRow(); row[FLD_Description] = "Quaderno"; row[FLD_Date] = DateTime.Now; row[FLD_Price] = 1.5; mDt.Rows.Add(row); row = mDt.NewRow(); row[FLD_Description] = "Penna"; row[FLD_Date] = DateTime.Now; row[FLD_Price] = 2.8; mDt.Rows.Add(row); row = mDt.NewRow(); row[FLD_Description] = "Gomma"; row[FLD_Date] = DateTime.Now; row[FLD_Price] = 0.7; mDt.Rows.Add(row); row = mDt.NewRow(); row[FLD_Description] = "Matita"; row[FLD_Date] = DateTime.Now; row[FLD_Price] = 1.1; mDt.Rows.Add(row); row = mDt.NewRow(); row[FLD_Description] = "Block notes"; row[FLD_Date] = DateTime.Now; row[FLD_Price] = 2.8; mDt.Rows.Add(row); row = mDt.NewRow(); row[FLD_Description] = "Pennarelli 12 colori"; row[FLD_Date] = DateTime.Now; row[FLD_Price] = 6.7; mDt.Rows.Add(row); mDt.AcceptChanges(); Mostra(); }
Il tasto Carica, aggiunge alcune righe alla DataTable e chiama la funzione Mostra che ne visualizza il contenuto sulla textbox.
private void Mostra() { this.txtResult.Text = string.Empty; for( int i=0; i< mDt.Rows.Count;i++) { MostraRiga(mDt.Rows[i]); } } private void MostraRiga(DataRow pRow) { this.txtResult.Text += "ID: " + pRow[FLD_ID].ToString() + Environment.NewLine; this.txtResult.Text += "Description: " + pRow[FLD_Description].ToString() + Environment.NewLine; this.txtResult.Text += "Date: " + pRow[FLD_Date].ToString() + Environment.NewLine; this.txtResult.Text += "Price: " + pRow[FLD_Price].ToString() + Environment.NewLine; this.txtResult.Text += Environment.NewLine; }
Il metodo Mostra utilizza MostraRiga per scrivere il contenuto delle righe sulla textbox.
private void btnAdd_Click(object sender, EventArgs e) { DataRow row = mDt.NewRow(); mDt.Rows.Add(row); row[FLD_Description] = string.Format("Nuova riga {0}", row[FLD_ID]); row[FLD_Date] = DateTime.Now; decimal pippo = Convert.ToDecimal(row[FLD_ID]); row[FLD_Price] = pippo*0.98m; mDt.AcceptChanges(); MostraRiga(row); }
Il bottone Aggiungi riga aggiunge una riga e passa la stessa a MostraRiga per la visualizzazione.
private void btnDelete_Click(object sender, EventArgs e) { DataRow row = mDt.Rows[0]; int id = Convert.ToInt32(row[FLD_ID]); row.Delete(); string filter = string.Format("{0} = {1}", FLD_ID, id); DataView vi = new DataView(mDt, filter,"", DataViewRowState.Deleted); DataTable tt = vi.ToTable(); mDt.AcceptChanges(); MostraRiga(tt.Rows[0]); }
Ed infine, il pezzetto di codice più interessante, il codice che ci permette di mostrare le informazioni relative alla riga cancellata.
Come potete vedere, il metodo cancella semplicemente la prima riga della DataTable salvandosi il suo ID.
Dopo la cancellazione, per poter leggere l’intera riga, creo una DataView che legge la riga appena cancellata e utilizza poi il metodo ToTable della DataView per mettere i dati in una nuova Tabella. Infine, passo la DataRow della nuova tabella alla funzione MostraRiga e posso vederne il contenuto nella mia textbox.
Il passaggio per ToTable è molto importante, infatti, se provassimo ad usare invece il codice seguente:
MostraRiga(vi[0].Row);
Che è perfettamente legale con una riga non cancellata, otterremo invece una Exception, perché non è permesso accedere direttamente ai dati di una riga cancellata.