[4] Il ritorno dello HockeyPlayer (data-binding con WPF)
Ci siamo lasciati l’ultima volta con il seguente screenshot:
Per sapere come ho ottenuto un risultato simile con WPF è sufficiente leggere i miei post precedenti (questo, questo e quest’altro). Impostando la proprietà ItemTemplate della ListBox, abbiamo fatto in modo che ogni riga venga visualizzata esattamente come vogliamo noi. Su ciascuna riga, vediamo tutti i dati che ci interessa vedere: nome del giocatore, peso ed altezza. Possiamo modificare quest’ultima agendo su ciascuno Slider. Divertente, no?
La cosa brutta è – come si vede sopra – il fatto che il binding tra lo Slider e la TextBox produce un effetto che non mi piace. La proprietà Value dello Slider è di tipo double, e quindi la proprietà Text della TextBox mostra un double, con tutti i decimali del caso. Se vogliamo fare le cose per bene, dobbiamo mettere mano al codice…oserei dire, finalmente. Dobbiamo realizzare una classe che implementa l’interfaccia IValueConverter: lo scopo di tale classe è quello di convertire i valori che vengono utilizzati nel processo di Binding. Nel nostro caso, nei due sensi:
- dallo Slider alla TextBox (quindi, da double a string)
- dalla TextBox allo Slider (quindi, da string a double)
Siccome mi piace l’idea che l’utente utilizzi lo Slider, eliminiamo la seconda possibilità: trasformiamo la TextBox in TextBlock. Immaginate la TextBlock come la classica Label delle Windows Form: visualizza qualcosa ma ovviamente non permette alcuna modifica. Lo vediamo fra un attimo. Detto questo, possiamo tranquillamente eliminare la conversione del punto (2): scriveremo lo stesso il codice perchè non siamo pigri, ma sappiamo a priori che non verrà utilizzato.
Arriviamo al dunque. Implementiamo una classe SliderValueConverter:
1 [ValueConversion(typeof(double), typeof(int))] 2 public class SliderValueConverter : IValueConverter 3 { 4 public object Convert(object value, Type targetType, 5 object parameter, 6 System.Globalization.CultureInfo culture) 7 { 8 double input = (double)value; 9 int output = (int)input; 10 return (output); 11 } 12 13 public object ConvertBack(object value, Type targetType, 14 object parameter, 15 System.Globalization.CultureInfo culture) 16 { 17 int input = (int)value; 18 double output = (double)input; 19 return (output); 20 } 21 }
L’implementazione dell’interfaccia IValueConverter è molto semplice: c’è un metodo Convert ed un metodo ConvertBack. Il primo converte da double ad integer. Il secondo da integer a double. In parole semplici: quando il Value dello Slider sta per essere spedito alla TextBox, passa prima dalla nostra classe, subìsce la conversione in intero ed arriva alla Text della TextBox. Basta impostare un breakpoint alla linea (8) per avere la conferma. 🙂
L’implementazione della classe SliderValueConverter da sola non è sufficiente per compiere la magia. Occorre modificare anche lo XAML, per fornire qualche informazione in più. Vediamo come e dove.
Inseriamo tra le risorse dello XAML un’istanza della classe SliderValueConverter:
<Window.Resources> <a:HockeyPlayers x:Key="players" /> <a:SliderValueConverter x:Key="conv"/> </Window.Resources>
Ricordo che con il prefisso a facciamo riferimento al namespace MyItemTemplate, che è il namespace col quale stiamo sviluppando l’applicazione. Poi prendiamo lo XAML che definisce la TextBox che viene bindata allo Slider e modifichiamolo come segue:
<TextBlock Margin="4" Text="{Binding ElementName=sldHeight, Path=Value, Converter={StaticResource conv}}" Width="60" />
Nel Binding abbiamo adesso forniamo l’ElementName, il Path ed infine il Converter, che per l’appunto fa uso della risorsa identificata dalla key conv. Compiliamo ed eseguiamo. Se tutto è ok, adesso quando spostiamo lo Slider vediamo qualcosa di un po’ più carino e leggibile (soprattutto per l’utente finale):
Stay tuned, perchè mica è finita qua! 🙂