Durante l'ultimo meeting di XeDotNet, ho presentato un piccolo esempio, che è piaciuto molto, che dimostra abbastanza bene alcuni aspetti del DataBinding in Windows Presentation Foundation. Quando per la prima volta mi sono addentrato nell'argomento, sono rimasto molto incuriosito di una peculiarità che riguarda poco il DataBinding tradizionale, ma che regala a WPF una marcia in più rispetto a Windows Forms.
Mi riferisco alla possibilità di collegare tra loro mediante DataBinding gli elementi che compongono una interfaccia e di conseguenza in qualche modo coordinarne movimenti, dimensioni, stili, contenuti e quant'altro. L'esempio più banale, che tipicamente introduce le presentazioni su WPF - comprese le mie - è quello di uno slider che modifica le dimensioni di un oggetto dell'interfaccia. Un esempio di questo tipo, anche se un po' banale però rivela bene e con semplicità la potenza di questo meccanismo. Tuttavia nell'ultimo meeting ho voluto trovare un esempio un po' più di impatto, e che includesse anche qualcosa in più rispetto alla pura e semplice dimostrazione.
Nello screencast cast che potete scaricare in coda a questo post è spiegato passo passo come realizzare l'esempio ritratto nell'immagine. Il giocattolo è costituito da tre ruote dentate, forgiate con Microsoft Expression Designer. Esse sono collegate tra loro mediante DataBinding:
1 <Path.RenderTransform>
2 <RotateTransform
3 x:Name="ruota2Anim"
4 Angle="{Binding ElementName=ruota1Anim,
5 Path=Angle,
6 Converter={StaticResource angleConverter},
7 ConverterParameter=-2.0}" />
8 </Path.RenderTransform>
Lo spezzone di codice mostra il punto cruciale dell'esempio. Si tratta di una trasformazione di rotazione, applicata al Path che costituisce una ruota. In particolare in questo caso si tratta della ruota gialla che è collegata a quella arancione. La proprietà Angle, cioè quella che determina l'angolo di rotazione applicato alla ruota, mostra l'applicazione del DataBinding mediante la Markup Extension "Binding". Al suo interno troviamo:
ElementName: Definisce il nome dell'elemento che funge da sorgente dati per la proprietà bindata. Nel nostro caso il riferimento è alla traformazione analoga applicata alla ruota arancione
Path: il nome della proprietà dell'elemento collegato dalla quale attingere. Per questo esempio ci colleghiamo alla stess proprietà Angle dell'elemento riferito.
Converter: Convertitore da utilizzare per calcolare il valore della proprietà. Utilizziamo una Markup Extension ancora una volta per riferire unìistanza di AngleConverter inserita nelle risorse della Window. Questo convertitore non fa altro che applicare un rapporto di demoltiplicazione all'angolo.
ConverterParameter: Parametro generico da passare al convertitore. Il parametro in questo caso sarà il fattore di demoltiplicazione da applicare alla ruota precedente.
1 <Canvas.Triggers>
2 <EventTrigger RoutedEvent="Canvas.Loaded">
3 <EventTrigger.Actions>
4 <BeginStoryboard>
5 <Storyboard Name="animation">
6 <DoubleAnimation
7 Duration="0:0:3.0"
8 To="360"
9 RepeatBehavior="Forever"
10 Storyboard.TargetName="ruota1Anim"
11 Storyboard.TargetProperty="Angle" />
12 </Storyboard>
13 </BeginStoryboard>
14 </EventTrigger.Actions>
15 </EventTrigger>
16 </Canvas.Triggers>
A Completare l'esempio, viene applicata una animazione alla ruota arancione. Per capire il risultato, che comunque è spiegato nella sua completezza nel video, bisogna pensare a come i dati vengono propagati. L'animazione si occupa di applicare una rotazione da 0 a 360 gradi alla ruota arancione. Mediante DataBinding questo valore, opportunamente demoltiplicato passa alla ruota gialla. Il rapporto di conversione è negativo perchè in questo modo la ruota girerà alla rovescia. Infine un analogo Binding avviene tra la ruota gialla e quella viola. Ancora una volta la conversione sarà negativa per far ruotare l'ingranaggio al contrario rispetto alla sua fonte.
Date un'occhiata al risultato e creto che rimarrete affascinati dalla precisione con cui le ruote si ingranano le une con le altre senza alcuna sovrapposizione e senza il minimo errore. Personalmente la cosa che mi alletta di più è pensare che grazie al DataBinding la simulazione del movimento si svolge proprio come si svolgerebbe nella realtà in cui ogni ruota applica una forza alla successiva trasferendole il movimento.