Faccio sempre una brutta faccia quando sento
parlare di data-binding.
In ambiente Visual Basic 6 ed affini, il
data-binding è un metodo che permette di "collegare" bidirezionalmente un
controllo ad una sorgente dati come, tipicamente, un database. Questo
collegamento era completamente trasparente per l'utente: era sufficiente
posizionare un controllo Data sul form o, più recentemente, un ADODC e impostare
qualche proprietà del controllo ed il gioco era fatto. Troppi automatismi
rendono il vita facile, è vero, ma tolgono allo stesso tempo controllo
lasciando poco spazio al programmatore per intervenire nel processo che, di
fatto, era gestito dal runtime di VB.
In ambiente .NET le cose sono radicalmente diverse. Data
l'architettura disconnessa di ADO.NET, non siamo mai veramente connessi al
database, se non durante l'operazione di Fill attuata dal
SqlDataAdapter. Di conseguenza, il data-binding in .NET permette, come
prima, di collegare un controllo ad una sorgente dati, ma nel
significato più ampio e generico del termine. Una sorgente dati infatti può
essere una banale variabile, una classe, una collection o, nei casi più utili,
una DataTable o un DataSet. Non solo: se prima con VB6 il controllo era legato
alla sorgente dati tramite la proprietà stabilita a priori dal creatore del
controllo, con .NET è tutto sotto il nostro controllo.
Vediamo, velocemente, come,
cosa, perchè e quando!
Colleghiamo una ListBox con una sorgente dati
Ho fatto
una prova veloce, semplice e, meraviglia, funzionante. Ho preso una WF, ho
posizionato una banale ListBox, ho creato un ArrayList con un
po' di elementi a caso. Poi, ho legato la ListBox con l'ArrayList. Il tutto con
una manciata di righe di codice C#:
lista = new ArrayList();
for(int i=1;i<11;i++)
lista.Add("elemento n." + i);
this.listBox1.DataSource = lista;
Il codice qui sopra popola l'ArrayList lista (definito come
private della WF) con 10 stringhe. Al termine
dell'esecuzione del codice qui sopra, la ListBox mostra tutti gli elementi
di lista. Questo automatismo è fornito gratis dal framework: se
un Control possiede le properties DataSource e/o
DataMember, possiamo impostarne la sorgente
dati. Questo è il caso più semplice, perchè il Control è sufficientemente
intelligente da conoscere come mostrare i dati: se è un Control di tipo
lista, allora semplicemente mostrerà tutti gli elementi. Così è per esempio per la ListBox o
per la ComboBox.
Se parliamo di data-binding, la DataGrid gioca un ruolo fondamentale. Essa possiede le
properties DataSource e DataMember, per cui possiamo riempirla di dati molto
velocemente tramite un bel DataSet riempito a dovere, tramite:
this.grdGriglia.DataSource = dsTabella;
Nulla di più semplice. Come ben sappiamo però, un DataSet può contenere più
di una tabella: se vogliamo mostrare direttamente il contenuto di una DataTable
specifica, possiamo farlo agendo su DataMember, che va
impostato sul nome della tabella stessa. La DataGrid dispone di diverse
caratteristiche comode, come la possibilità di ordinare i records agendo sugli
headers della griglia.
Io mi sono divertito ad impostare un DataView come
DataSource della griglia. Il DataView rappresenta una vista su
una DataTable specifica. Usandolo, ho usato le proprietà
Sort e RowFilter per riordinare la griglia
come volevo, o per filtrarne i dati.
Fare data-binding su una
TextBox
Complichiamoci la vita. La TextBox non dispone di DataSource e DataMember,
però possiamo comunque fare binding in modo interessante utilizzando la property
DataBindings. Questa property è in realtà una collection di
oggetti Binding che consente di creare un collegamento (come
dicevo prima) tra controllo e sorgente dati indicando: property del controllo,
nome della sorgente ed eventuale campo della sorgente dati. Ultima nota:
trattandosi di una TextBox, vedremo un solo elemento alla volta della sorgente
dati. Il caso più semplice e banale (leggere inutile) è questo:
string testo = "pippo";
Binding bnd = new Binding("Text", testo, null);
this.textBox1.DataBindings.Add(bnd);
Nonostante la semplicità, possiamo già dedurre una cosa importante. La
variabile testo può essere qualsiasi contenitore di dati, e
null è il nome della property del contenitore. Per esempio, ho
creato una classe Auto con tre proprietà: marca, modello e
numero di porte. Ho creato una property GetCompleteName che mi
ritorna una string formata dalla concatenazione di marca + modello. Ho fatto un
semplice data binding con le seguenti linee di codice:
Auto mia = new Auto("Opel", "Astra 1.6", 4);
Binding bnd = new Binding("Text", mia, "GetCompleteName");
this.textBox1.DataBindings.Add(bnd);
Quando avvio il progetto, la TextBox contiene la string "Opel Astra 1.6". Con
le righe qui sopra, ho collegato la property Text della
TextBox con la property GetCompleteName della
mia classe Auto. Attenzione che GetCompleteName deve essere
implementata come una property (keyword get) e non come metodo:
il binding in quest'ultimo caso non funziona.
Lasciatemi fare qualche esperimento interessante, e proseguirò sul discorso
data-binding.
Tutti i commenti del caso sono assolutamente graditi!!!