Post dopo studio. Un interessante funzionalità del motore di binding in WPF è quella di permettere il binding tra proprietà di elementi. Ad esempio, supponiamo di avere una Window Form VPW con due controlli TextBox (txtOne e txtTwo). Vogliamo che al cambiare del Background della prima, venga cambiato automaticatimente anche il Background della seconda (senza scrivere una riga di codice C#/VB.NET). Il codice XAML che effettua questa "magia" è il seguente:
1 <TextBox Margin="57,127,53,112" Name="txtOne" Background="Sienna" /> 2 <TextBox Margin="57,156,53,83" Name="txtTwo" Background="{Binding Path=Background, ElementName=txtOne}" />
Il risultato del binding che si ottiene può essere verificato anche a design-time cambiando il colore di background di txtOne. Proviamo a complicarci la vita. Supponiamo che i due controlli TextBox siano utilizzati come campi contenenti valori da sommare. Vogliamo impostare il background di un terzo controllo Textbox (txtResult) secondo che il risultato della somma sia minore-uguale o maggiore di un certo valore soglia, ad esempio 100. Per completare questo obiettivo abbiamo la necessità di utilizzare un Converter , o meglio costruire una classe che implementi l'interfaccia IValueConverter. Utilizzando questa interfaccia, possiamo applicare del codice custom alla logica di binding. Ad esempio nel nostro esempio dobbiamo convertire un valore intero in un'istanza di oggetto Brush. E' necessario implementare i due metodi esposti dall'interfaccia IValueConverter: Convert e ConvertBack. Il primo entra in gioco, chiamato in causa dal binding engine, quando un valore deve essere propagato (converito) dalla sorgente al binding al target. Questo metodo ritorna il valore convertito o null. Il metodo ConvertBack, come suggerisce il nomestesso, esegue il processo contrario a quello di Convert.
Per Convert e ConvertBack, il valore di ritorno, invece di essere null, può anche essere DependencyProperty.UnsetValue, se la conversione non ha prodotto valore e si vuole utilizzare la proprietà FallBackValue (se disponisbile) o il valore di default. Per l'esempio corrente non è necessario eseguire nessuna conversione dal target al source , quindi non scriviamo nessun codice per il metodo ConvertBack, ma è sufficiente ritornrare il valore DependencyProperty.UnsetValue o null.
Il codice della classe che esegue la conversione tra Binding Source e Binding Target è il seguente:
1 public class MyValueConverter : IValueConverter
2 {
3 #region IValueConverter Members 4 5 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
6 {
7 try 8 {
9 int result = 0;
10 if (int.TryParse(value.ToString(), out result))
11 {
12 return (result>100 ? Brushes.Red : Brushes.Green );
13 }
14 else 15 return DependencyProperty.UnsetValue;
16 }
17 catch
18 {
19 return DependencyProperty.UnsetValue;
20 }
21 }
22 23 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
24 {
25 return DependencyProperty.UnsetValue;
26 }
27 28 #endregion 29 }
Creiamo un'istanza della classe MyValueConverter direttamente nel codice XAML, aggiungendola alla collezione delle risorse della nostra Window WPF:
1 <local:MyValueConverter x:Key="MyConverter" />
A questo punto non ci resta che impostare il binding del controllo TextBox (txtResult) tra la proprietà Text (source) e Background (Target) del controllo stesso
1 <TextBox Height="23" Margin="57,0,53,54" Name="txtResult" VerticalAlignment="Bottom"
2 Background="{Binding Path=Text, ElementName=txtResult, Converter={StaticResource MyConverter}}"
3 TextAlignment="Right" Foreground="White" />
Per eseguire la somma dei valori contenuti nei due TextBox, utilizziamo un controllo Button con associato il seguente codice C#:
1 int a = int.Parse(txtOne.Text);
2 int b = int.Parse(txtTwo.Text);
3 int r = a + b;
4 txtResult.Text = r.ToString();
In questo modo, il Background di txtResult cambierà in base al valore della somma ottenuta.