Per alcuni elementi, esistono delle proprietà che non sono relative all'oggetto stesso, queste classi conferiscono proprietà agli oggetti figlio, chiamate Attached Properties.
Sono una forma particolare di Dependency Property e vengono definite nella solita modalità, ma non dispongono di proprietà wrapper per facilitarne l'utilizzo e hanno una sintassi speciale in XAML:
Sintassi delle Attached Properties
ParentElement.PropertyName
Le informazioni definite negli elementi figlio, tramite l'uso di Attached Properties,vengono utilizzate dall'oggetto padre per definire il layout dei controlli.
Nell'esempio successivo utilizziamo le Attached Properties: Canvas.Top
e Canves.Left
per definire la posizione di un Rectangle
all'interno di un Panel
di tipo Canvas
.
<Canvas x:Name="LayoutRoot" Width="100" Height="100">
<Rectangle Canvas.Top="10" Canvas.Left="20" Fill="Black"
Height="50" Width="100" />
</Canvas>
Per le Attached Properties, valgono regole derivate delle Dependency Properies: l'eredità di DependencyObject
o FrameworkElement
e la convenzione dei nomi. La differenza sostanziale fra le due proprietà sta nella modalità di accesso in lettura e scrittura, che nelle Attached Properties avviene tramite i metodi statici GetPropertyName
e SetPropertyName
.
Ad esempio, nel frammento di codice precedente, il controllo Canvas
non espone una proprietà Top
, ma due metodi GetTop
e SetTop
.
Chiaramente anche i passi per definire una Attached Property sono simili a quelli per una Dependency Property, vediamoli:
- definire un membro statico pubblico di tipo
System.Windows.DependencyProperty
- registrare la proprietà nel costruttore statico della classe attraverso una chiamata al metodo
DependencyProperty.RegisterAttached
il quale richiede come parametri, il nome, il tipo della proprietà, il tipo della classe che la espone e il metodo di callback che viene invocato quando il valore della proprietà cambia - definire due metodi statici pubblici per le operazioni di get e set utilizzando la convenzione
GetPropertyName
e SetPropertyName per la definizione dei nomi dei metodi
Per esempio definiamo una proprietà Left
di tipo double
per una classe AttachedPropertyDemo
:
public class AttachedPropertyDemo : DependencyObject { public static readonly DependencyProperty LeftProperty; static AttachedPropertyDemo() { LeftProperty = DependencyProperty.RegisterAttached( "Left", typeof(double), typeof(AttachedPropertyDemo), new PropertyMetadata(new PropertyChangedCallback(OnLeftPropertyChanged))); } public static double GetLeft(UIElement element) { return (double)element.GetValue(LeftProperty); } public static void SetLeft(UIElement element, double length) { element.SetValue(LeftProperty, length); } private static void OnLeftPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { <span class="commento">//qui va inserita l'eventuale logica applicativa</span> <span class="commento">//da eseguire quando il valore della proprietà è stato modoficato</span> } }