Capita di rado, ma talvolta è necessario poter definire il binding di una proprietà da codice anzichè dal markup XAML. In questi casi tradurre la normale sintassi basata su una Markup Extension in codice vero e proprio non è immediato. Io stesso ho dovuto cercare un bel po’ prima di capire quali sono gli oggetti coinvolti e arrivare a tradurre i tutto in poche righe di codice C#.

Ma partiamo da un ipotetico Binding effettuato come di consueto da XAML:

   1: <TextBox x:Name="txtFirstName" Text="{Binding FirstName, Mode=TwoWay}" />

In questa singola riga è racchiuso e semplificato un po’ di codice. Innanzitutto la creazione di un oggetto che si occupa di fare il DataBinding e che incapsula le proprietà che abbiamo valorizzato, in questo caso Source e Mode, ma volendo anche alte come ad esempio il Converter e i suoi parametri. Infine l’assegnazione di questo oggetto alla proprietà che deve essere bindata.

Ecco in soldoni il codice che andrebbe scritto per simulare la Markup Extensione di cui sopra:

   1: // crea l'oggetto che contiene i parametri del binding
   2:  
   3: Binding binding = new Binding("FirstName")
   4: {
   5:     // sorgente del binding (DataContext)
   6:     Source = source,
   7:  
   8:     // modalità di binding
   9:     Mode = mode
  10: };
  11:  
  12: // assegno il binding alla textbox
  13:  
  14: element.SetBinding(TextBox.TextProperty, binding);

Questo non è molto codice, ma scriverlo ripetutamente magari su decine di proprietà è piuttosto laborioso e può aprire la strada a errori e omissioni. E allora perchè non scrivere un metodo che lo incapsuli. Anzi, visto che parliamo di usare il framework 3.5 la soluzione migliore è di scrivere un certo numero di Extension Methods che mettano a disposizione un po’ di overload per i casi più disparati:

   1: public static void Bind(
   2:     this FrameworkElement element, 
   3:     DependencyProperty property, 
   4:     string path, 
   5:     object source, 
   6:     BindingMode mode, 
   7:     IValueConverter converter, 
   8:     object converterParameter, 
   9:     CultureInfo converterCulture)
  10: {
  11:     Binding binding = new Binding(path)
  12:     {
  13:         Source = source,
  14:         Mode = mode
  15:     };
  16:  
  17:     if (converter != null)
  18:     {
  19:         binding.Converter = converter;
  20:         binding.ConverterCulture = converterCulture ?? CultureInfo.CurrentCulture;
  21:         binding.ConverterParameter = converterParameter;
  22:     }
  23:  
  24:     element.SetBinding(property, binding);
  25: }

In questo spezzone di codice viene mostrata la versione più ampia dei metodi in questione, cioè quella che accetta più parametri. Lascio a voi scegliere la combinazione di parametri che più vi aiuta. Se poi volete i miei vi segnalo che questa classe sarà disponibile nella prossima release della mia Silverlight Library 1.0. Ma vediamo come usare i metodi in questione dimostrando una versione con un po’ meno di parametri:

   1: txtFirstName.Bind(TextBox.TextProperty, "FirstName", source, BindingMode.TwoWay);

Questa riga effettua esattamente lo stesso binding dell’esempio scritto in XAML poco sopra. Siamo così riusciti nell’intento di semplificare il lavoro e di ridurre soprattutto la quantità di codice da scrivere.


Aggiungi Commento