Nel precedente post ho mostrato come è facile connettere UI e dati in WPF, a questo punto ci si può domandare: Ma come avviene la conversione tra il tipo esposto dalla proprietà sorgente e quello di destinazione?
La rispostà è attraverso dei TypeConverters i quali hanno il compito di convertire il tipo sorgente in quello destinazione, nel caso specifico dell'esempio precendente il converter utilizzato è uno StringConverter.
Ma se dovessimo mettere in binding una proprietà di tipo Custom?: In questo caso dobbiamo associare al Binding un nostro TypeConverter definendo una classe che implementa IValueConverter.
La creazione di un custom converter si rende necessaria anche quando dobbiamo gestire altri dettagli di conversione da e verso i dati, nello specifico la formattazione.
Supponiamo di volere mettere in Binding un istanza di questa classe:
class DBData {
private double mValue1=12.345;
public double Value1{
get { return mValue1; }
set { mValue1 = value; }}
}
Lo XAML equivalente sarà:
<Grid>
<Grid.Resources>
<c:DBData x:Key="dbData" />
</Grid.Resources>
<TextBlock Text="{Binding Source={StaticResource dbData},Path=Value1,"/>
</Grid>
e questo il risultato.
Ma se volessimo formattare l'output e visualizzare solo una cifra decimale?
La risposta è: Associare un custom converter creando una classe che implementa IValueConverter
public class NumConverter : IValueConverter
{
public object Convert (object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
try{return System.Convert.ToInt32(value).ToString(parameter as string); }
catch (Exception ex){return DependencyProperty.UnsetValue;}
return value;
}
public object ConvertBack (object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
return null;
}}
Notate come ad entrambi i metodi sia possibile passare un parametro che nel caso della Convert viene passato direttamente al metodo ToString()
A questo punto il converter va utilizzato in questo modo:
<Grid>
<Grid.Resources>
<c:DBData x:Key="dbData" />
<c:NumConverter x:Key="NumConv" />
</Grid.Resources>
<TextBlock Text="{Binding Source={StaticResource dbData},Path=Value1,Converter={StaticResource NumConv},ConverterParameter=0.0,FallbackValue=??? }"/>
</Grid>
Attraverso l'attributo Converter ho indicato il convertitore da usare, ConverterParameter è il parametro che verrà passato e che, in questo caso, rappresenta la stringa di formattazione mentre FallbackValue è il valore che verrà mostrato nel caso il metodo Convert fallisca.
Il risultato è quello qui a fianco.