Daily Issue speciale della domenica :) Sto litigando da parecchi giorni con Silverlight (ma no? Ma dai? :P) come sicuramente chi legge anche solo ogni tanto il mio blog avrà capito.
A causa di questo amore/odio, sono dovuto scendere a patti con le AttachedProperties che, per chi non lo sapesse, sono proprietà che possono essere associate ad un figlio da un padre, senza che il figlio abbia conoscenza del padre stesso.
Sono vitali in Silverlight in quanto tutta la struttura è formata in termini di padre/figlio e la maggior parte degli oggetti deve interagire con le proprietà del canvas contenitore.
Cambiare queste proprietà modificando lo XAML è relativamente semplice, mentre cambiarle da codice per creare effetti dinamici può rivelarsi abbastanza complesso.
Per fortuna, basta cercare meglio nella (scarna) documentazione, e controllare bene gli oggetti DependencyObject e DependencyProperty. DependencyObject è un qualsiasi oggetto che può essere sottoposto a questo genere di dipendenza, quindi piu o meno qualsiasi oggetto presente in Silverlight (MediaElement, Textblock, Image e compagnia danzante). DependencyProperty è appunto un'istanza di una proprietà "attaccata" da un padre sul figlio.
Cercando piu a fondo, e "dribblando" alcuni consigli errati sull'utilizzo degli Attributes in maniera diretta, si scropre che ogni DependencyObject espone due metodi SetValue e GetValue, per scrivere e leggere rispettivamente le nostre attachedProperty.
Quindi, avendo un MediaElement e volendo cambiare il Canvas.Top, si può usare
MediaElement m = new MediaElement();
m.SetValue(Canvas.TopProperty, 100);
In questo modo il mio MediaElement verrà renderizzato con 100 pixel di margine rispetto al margine superiore del mio canvas.
Volendo farne una questione di concetto, cmq questo approccio non è esattamente giusto: dovrebbe essere la classe Canvas ad esporre le giuste proprietà per cambiare le attached properties sui figli.
Ed infatti, è proprio così: la classe che gestisce le dipendenze _deve_ esporre dei metodi statici che permettano di cambiare le properties sui figli.
Quindi, volendo cambiare il nostro esempio, si avrebbe
MediaElement m = new MediaElement();
Canvas.SetTop(m, 100);
Più o meno la stessa cosa... ma più carino :)
Update: ho scoperto girovagando questo post che dice piu o meno le stesse cose che dico qui... dateci un occhio perchè va molto piu nel dettaglio rispetto a quanto sono andato io :)