17.5 Abhängige und angehängte Eigenschaften 

WPF erweitert die Eigenschaften der Common Language Runtime (CLR) um zwei besondere Gruppen:
- abhängige Eigenschaften (Dependency Properties)
- angehängte Eigenschaften (Attached Properties)
Beide werden wie »normale« Eigenschaften verwendet, aber anders deklariert.
17.5.1 Abhängige Eigenschaften 

Stellen Sie sich vor, im Auslieferungslager eines Unternehmens befindet sich der Artikel A. Mit dem Artikel ist ein bestimmter Verkaufspreis verknüpft. Wird der Artikel ins Ausland verkauft, in dem eine andere Währung Zahlungsmittel ist, muss der Verkaufspreis eventuell an den aktuellen Wechselkurs dynamisch angepasst werden. Damit wäre der Verkaufspreis der typische Fall einer abhängigen Eigenschaft.
Abhängige Eigenschaften bieten im Vergleich mit den herkömmlichen Eigenschaften Vorteile:
- Die Werte werden automatisch aktualisiert.
- Zur Signalisierung von Wertänderungen werden Callback-Methoden verwendet.
- Es kann eine interne Validierung erfolgen.
- Es können Standardwerte definiert werden.
Die Einführung von abhängigen Eigenschaften war notwendig, um die vielen WPF-Konzepte realisieren zu können, da einige davon abhängen, ob sich im System oder in der Anwendung Eigenschaftswerte verändert haben. Zu den Features, die grundlegend auf abhängige Eigenschaften angewiesen sind, gehören beispielsweise die Datenbindung, Ressourcen und Animationen.
An einem Beispiel wollen wir uns nun ansehen, wie eine abhängige Eigenschaft in einer Klasse definiert wird. Dazu definieren wir eine Klasse Line, die von DependencyObject abgeleitet wird.
class Line : DependencyObject { // die abhängige Eigenschaft public static readonly DependencyProperty LengthProperty; // Registrieren der abhängigen Eigenschaft static Line() { Line.LengthProperty = DependencyProperty.Register( "Length", typeof(int), typeof(Line), new FrameworkPropertyMetadata(10, new PropertyChangedCallback(OnLengthChanged))); } // Schnittstelle der Eigenschaft nach draußen public int Length { get { return (int)GetValue(Line.LengthProperty); } set { SetValue(Line.LengthProperty, value); } } // Callback-Methode private static void OnLengthChanged(DependencyObject dpObj, DependencyPropertyChangedEventArgs e) { // ... } }
Abhängige Eigenschaften sind vom Typ DependencyProperty. Sie müssen als öffentliche statische Felder definiert werden. Die Verwaltung abhängiger Eigenschaften wird vom WPF-Subsystem übernommen. Aus diesem Grund müssen abhängige Eigenschaften mit der Methode Register registriert werden. Dem Aufruf werden der Name der Eigenschaft (hier: Length), der Typ der Eigenschaft und die Klasse übergeben, die die abhängige Eigenschaft hostet. Zudem werden bei der Registrierung ein Standardwert und eine Rückrufmethode festgelegt.
In der Eigenschaftsmethode werden GetValue und SetValue aufgerufen. Beide sind Eigenschaften der Klasse DependencyObject. GetValue liefert den letzten an SetValue gelieferten Wert. Solange SetValue nicht aufgerufen worden ist, wird der Standardwert zurückgeliefert. Genau genommen muss keine Eigenschaftsmethode implementiert werden, da GetValue und SetValue öffentlich in DependencyObject definiert sind.
Von der Callback-Methode werden schließlich alle Wertänderungen überwacht.
17.5.2 Angehängte Eigenschaften 

Eine besondere Variante der abhängigen Eigenschaften sind die angehängten Eigenschaften (Attached Properties). Abhängige Eigenschaften sind in einem übergeordneten Element definiert. Üblicherweise handelt es sich dabei um einen Container wie beispielsweise um Grid oder StackPanel. Angehängte Eigenschaften stehen in einem untergeordneten Element zur Verfügung, ohne dass die Eigenschaft in diesem definiert ist. Der Vorteil bei diesem Verfahren ist, dass sich die Anzahl der eigentlichen Eigenschaften für die Komponente verringert.
Betrachten wir dazu ein Beispiel. In einem Grid soll eine TextBox positioniert werden. Die Eigenschaften Grid.Column und Grid.Row sind Eigenschaften, die vom Grid der TextBox zur Verfügung gestellt werden.
<Grid> <TextBox Grid.Column="0" Grid.Row="0" Name="txtText" >Hallo</TextBox> </Grid>
Sie können die Position der TextBox auch mittels Code ändern, müssen dann aber die Eigenschaften SetColumn und SetRow des Grid-Controls aufrufen.
Grid.SetColumn(txtText, 1); Grid.SetRow(txtText, 2);