Il data binding è una delle funzionalità più interessanti, e potenti, di .NET. La sua forza, a parer mio, sta nella sua versatilità la quale, spesso e volentieri, si trasforma in oscurità. La documentazione, ainoi, non è sempre molto chiara sul DataBinding, soprattutto nel contesto Object Oriented. Mentre è tuttosommato facile collegare una DataGrid ad una Dataset o DataTable (ecc...), lo diventa meno quando dobbiamo collegare i controlli ad oggetti.

In primis, ho sempre avuto il dubbio che per collegare un attributo di un oggetto ad un controllo (es. TextBox), si dovesse ricorrere sempre a proprietà e non campi, pena una bella eccezione stile "DataBinder.Eval: 'WebStudy.Persona' does not contain a property with the name Nome". Questo mi spingeva a scrivere la classe come segue:

public class Persona {
  private string _nome;

  public string Nome {
    get { return _nome; }
    set { _nome = value; }
  }
}

Quando le proprietà di una classe sono tante, è veramente impraticabile come strada (oltre che noiosa per chi la scrive). Volevo quindi scrivere le mie classi come segue:

public class Persona {
  public string Nome;
}

in quanto non dovevo avere comportamenti particolari della proprietà (sola lettura/scrittura o codice di controllo). Ma come mappare un campo invece di una proprietà ? La risposta è banale (anche se ho impiegato 1 ora a capire come fare :-S ). Basta dichiarare una variabile protected nella classe della pagina di tipo Persona (es p) e invocare il DataBind() di Page. Nel code ASP.NET è necessario richiamare la proprietà dell'oggetto:

<asp:TextBox id="TextBox1" runat="server" Text='<%# p.Nome %>'></asp:TextBox>

La variabile p deve essere protected (o public) in quanto la pagina ASP.NET in esecuzione è una classe derivata dalla nostra classe nel code-behind. Se la dichiarassimo come private avremmo un'eccezione "'WebStudy.MyDataBind.p' is inaccessible due to its protection level".

Detto questo, vediamo di complicare un attimo la vita. Che succede con un array di oggetti che contengono campi e non proprietà ? Aggiungo alla classe Persona un array di indirizzi:

public class Persona {
 public string Nome;

 public ArrayList Indirizzi;

 public Persona()  {
  Indirizzi = new ArrayList();
 }
}

public class Indirizzo {
 public string email;

 public Indirizzo() {
 }

 public Indirizzo(string email) {
  this.email = email;
 }
}

Inserisco una Datagrid nella form e inizializzo il tutto:

p = new Persona();
p.Nome = "Leonardo";
p.Indirizzi.Add(new Indirizzo("leonardo@davinci.it"));

DataGrid1.DataSource = p.Indirizzi;
this.DataBind();

Lato ASP.NET non posso usare le Bound Columns in quanto si aspettano delle proprietà e non campi. Quindi opto per template column

<asp:DataGrid id="DataGrid1" runat="server" AutoGenerateColumns="False">
 <Columns>
  <asp:TemplateColumn HeaderText="EMail">
   <ItemTemplate>
    <%# (Container.DataItem as WebStudy.Indirizzo).email %>
   </ItemTemplate>
  </asp:TemplateColumn>
 </Columns>
</asp:DataGrid>

Dato che il contenuto della lista sono degli indirizzi, basta castare il DataItem sull'indirizzo ed estrabolare l'email corrispondente. Il gioco è fatto ! Ho risparmiato parecchie righe di codice mantenendo la flessibilità offerta da .NET.