Übersicht über angefügte Eigenschaften

Eine angefügte Eigenschaft ist ein Extensible Application Markup Language (XAML)-Begriff. Angefügte Eigenschaften sollen als Typ einer globalen Eigenschaft verwendet werden, die für jedes Objekt festgelegt werden können. In Windows Presentation Foundation (WPF) sind angefügte Eigenschaften normalerweise als Sonderform einer Abhängigkeitseigenschaftdefiniert, die nicht den herkömmlichen Eigenschaftenwrapper besitzt.

Dieses Thema enthält folgende Abschnitte.

  • Vorbereitungsmaßnahmen
  • Gründe für die Verwendung von angefügten Eigenschaften
  • Angefügte Eigenschaften in XAML
  • Verwendung der angefügten Eigenschaften durch den besitzenden Typ
  • Angefügte Eigenschaften in Code
  • Metadaten von angefügten Eigenschaften
  • Benutzerdefinierte angefügte Eigenschaften
  • Weitere Informationen – Angefügte Eigenschaften
  • Verwandte Abschnitte

Vorbereitungsmaßnahmen

In diesem Thema wird vorausgesetzt, dass Sie sich mit Abhängigkeitseigenschaften aus Sicht eines Consumers vorhandener Abhängigkeitseigenschaften von Windows Presentation Foundation (WPF)-Klassen auskennen und dass Sie die Übersicht über Abhängigkeitseigenschaften gelesen haben. Um die Beispiele in diesem Thema verfolgen zu können, sollten Sie mit der Verwendung von Extensible Application Markup Language (XAML) und dem Schreiben von WPF-Anwendungen vertraut sein.

Gründe für die Verwendung von angefügten Eigenschaften

Ein Zweck einer angefügten Eigenschaft besteht darin, es verschiedenen untergeordneten Elementen zu ermöglichen, eindeutige Werte für eine Eigenschaft anzugeben, die eigentlich in einem übergeordneten Element definiert ist. Eine spezielle Anwendung dieses Szenarios ist zum Beispiel, wenn untergeordnete Elemente das übergeordnete Element darüber informieren, wie sie in der user interface (UI) dargestellt werden sollen. Ein Beispiel hierfür ist die DockPanel.Dock-Eigenschaft. Die DockPanel.Dock-Eigenschaft wird als angefügte Eigenschaft erstellt, da sie für die Festlegung für Elemente gedacht ist, die sich innerhalb von DockPanel befinden, nicht für DockPanel selbst. Die DockPanel-Klasse definiert das statische Feld DependencyProperty mit dem Namen DockProperty und stellt dann die Methoden GetDock und SetDock als öffentliche Accessoren für die angefügte Eigenschaft bereit.

Angefügte Eigenschaften in XAML

In XAML legen Sie angefügte Eigenschaften fest, indem Sie die Syntax AttachedPropertyProvider.PropertyName verwenden. 

Unten folgt ein Beispiel dafür, wie Sie DockPanel.Dock in XAML festlegen können:

<DockPanel>
  <CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>

Beachten Sie, dass die Verwendung einer statischen Eigenschaft ähnelt. Sie verweisen jeweils auf den Typ DockPanel, der die angefügte Eigenschaft besitzt und registriert, anstatt auf eine Instanz zu verweisen, die über den Namen angegeben ist.

Da es sich bei einer angefügten Eigenschaft in XAML um ein Attribut handelt, das Sie in Markup festlegen, ist außerdem nur die Set-Operation relevant. Sie können in XAML eine Eigenschaft nicht direkt abrufen, obwohl einige indirekte Mechanismen zum Vergleichen von Werten vorhanden sind, zum Beispiel Trigger in Stilen (ausführliche Informationen finden Sie unter Erstellen von Formaten und Vorlagen).

Implementierung von angefügten Eigenschaften in WPF

In Windows Presentation Foundation (WPF) werden die meisten der angefügten Eigenschaften, die in WPF-Typen vorhanden sind, als Abhängigkeitseigenschaften implementiert. Angefügte Eigenschaften sind ein XAML-Begriff, während Abhängigkeitseigenschaften ein WPF-Begriff sind. Da es sich unter WPF bei angefügten Eigenschaften um Abhängigkeitseigenschaften handelt, unterstützen sie Begriffe der Abhängigkeitseigenschaften wie Eigenschaftenmetadaten und die dazugehörigen Standardwerte.

Verwendung der angefügten Eigenschaften durch den besitzenden Typ

Obwohl angefügte Eigenschaften für jedes Objekt festgelegt werden können, bedeutet dies nicht automatisch, dass das Festlegen der Eigenschaft zu einem greifbaren Ergebnis führt oder dass der Wert jemals von einem anderen Objekt verwendet wird. Im Allgemeinen werden angefügte Eigenschaften mit der Absicht verwendet, dass Objekte, die aus den verschiedensten Klassenhierarchien oder logischen Beziehungen stammen, jeweils gemeinsame Informationen an den Typ melden können, der die angefügte Eigenschaft definiert. Der Typ, der die angefügte Eigenschaft definiert, folgt in der Regel einem dieser Modelle:

  • Der Typ, der die angefügte Eigenschaft definiert, ist so konzipiert, dass er das übergeordnete Element der Elemente sein kann, die die Werte für die angefügte Eigenschaft festlegen. Der Typ durchläuft seine untergeordneten Objekte dann mithilfe von interner Logik entsprechend der Objektstruktur, ruft die Werte ab und führt basierend auf den Werten entsprechende Schritte aus.

  • Der Typ, der die angefügte Eigenschaft definiert, wird als untergeordnetes Element für verschiedene mögliche übergeordnete Elemente und Inhaltsmodelle verwendet.

  • Der Typ, der die angefügte Eigenschaft definiert, stellt einen Dienst dar. Andere Typen legen Werte für die angefügte Eigenschaft fest. Wenn das Element, das die Eigenschaft festgelegt hat, dann im Kontext des Dienstes ausgewertet wird, werden die Werte der angefügten Eigenschaft mithilfe der internen Logik der Dienstklasse abgerufen.

Beispiel für eine von einem übergeordneten Element definierte angefügte Eigenschaft

Das häufigste Szenario, bei dem WPF eine angefügte Eigenschaft definiert, besteht darin, dass ein übergeordnetes Element eine Auflistung untergeordneter Elemente unterstützt und zusätzlich ein Verhalten implementiert, bei dem die spezifischen Merkmale des Verhaltens für jedes untergeordnete Element einzeln gemeldet werden.

DockPanel definiert die angefügte DockPanel.Dock-Eigenschaft, und DockPanel verfügt als Teil der Renderinglogik über Klassenebenencode (MeasureOverride und ArrangeOverride). Eine DockPanel-Instanz prüft immer, ob eines ihrer direkt untergeordneten Elemente für DockPanel.Dock einen Wert festgelegt haben. Wenn dies der Fall ist, werden diese Werte zur Eingabe für die Renderinglogik, die auf das jeweilige untergeordnete Element angewendet wird. Geschachtelte DockPanel-Instanzen behandeln jeweils ihre eigenen Auflistungen direkt untergeordneter Elemente. Dieses Verhalten richtet sich jedoch spezifisch für die jeweilige Implementierung danach, wie das DockPanel-Element die DockPanel.Dock-Werte verarbeitet. Es ist theoretisch möglich, angefügte Eigenschaften zu verwenden, die sich auf Elemente über das unmittelbar übergeordnete Element hinaus auswirken. Wenn die angefügte DockPanel.Dock-Eigenschaft für ein Element festgelegt wird, das nicht über ein übergeordnetes DockPanel-Element verfügt, das auf dieses Element wirkt, wird kein Fehler und keine Ausnahme ausgelöst. Dies bedeutet lediglich, dass ein globaler Eigenschaftswert festgelegt wurde, der jedoch kein übergeordnetes DockPanel-Element aufweist, das die Informationen verwenden könnte.

Angefügte Eigenschaften in Code

Angefügte Eigenschaften in WPF verfügen nicht über die typischen CLR-Wrappermethoden für den einfachen get/set-Zugriff. Dies liegt daran, dass die angefügte Eigenschaft nicht zwingend Teil des CLR-Namespace für Instanzen ist, für die die Eigenschaft festgelegt ist. Ein XAML-Reader muss jedoch dazu in der Lage sein, diese Werte festzulegen, wenn XAML verarbeitet wird. Damit es sich um eine effektive angefügte Eigenschaft handelt, muss der Besitzertyp der angefügten Eigenschaft dedizierte Accessormethoden der Form GetPropertyName und SetPropertyName implementieren. Diese dedizierten Accessormethoden sind außerdem nützlich, um die angefügte Eigenschaft im Code festzulegen bzw. abzurufen. Aus Codesicht ähnelt eine angefügte Eigenschaft einem dahinter liegenden Feld, das anstelle von Eigenschaftenaccessoren über Methodenaccessoren verfügt. Das dahinter liegende Feld kann für ein Objekt vorhanden sein und muss nicht speziell definiert werden.

Das folgende Beispiel zeigt, wie Sie im Code eine angefügte Eigenschaft festlegen können. In diesem Beispiel ist myCheckBox eine Instanz der CheckBox-Klasse.

      Dim myDockPanel As New DockPanel()
      Dim myCheckBox As New CheckBox()
      myCheckBox.Content = "Hello"
      myDockPanel.Children.Add(myCheckBox)
      DockPanel.SetDock(myCheckBox, Dock.Top)
DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);

Es ist folgende Ähnlichkeit zum XAML-Fall zu beobachten: Wäre myCheckBox nichts bereits in der dritten Codezeile als untergeordnetes Element von myDockPanel hinzugefügt worden, würde die vierte Zeile keine Ausnahme auslösen, aber der Eigenschaftswert würde auch nicht mit einem übergeordneten DockPanel-Element interagieren und somit nichts bewirken. Nur ein DockPanel.Dock-Wert, der für ein untergeordnetes Element in Kombination mit dem Vorhandensein eines übergeordneten DockPanel-Elements festgelegt wird, ruft in der gerenderten Anwendung ein Verhalten hervor. (In diesem Fall könnten Sie die angefügte Eigenschaft festlegen und dann an die Struktur anfügen. Oder Sie könnten die angefügte Eigenschaft an die Struktur anfügen und dann festlegen. Das Ergebnis ist unabhängig von der Reihenfolge dasselbe.)

Metadaten von angefügten Eigenschaften

Beim Registrieren der Eigenschaft wird FrameworkPropertyMetadata festgelegt, um die Merkmale der Eigenschaft anzugeben, zum Beispiel ob sich die Eigenschaft auf das Rendering, die Messung usw. auswirkt. Die Metadaten für eine angefügte Eigenschaft unterscheiden sich im Allgemeinen nicht von denen einer Abhängigkeitseigenschaft. Wenn Sie in einer Überschreibung für die Metadaten einer angefügten Eigenschaft einen Standardwert angeben, wird dieser Wert zum Standardwert der impliziten angefügten Eigenschaft von Instanzen der überschreibenden Klasse. Der Standardwert wird gemeldet, wenn ein Prozess den Wert einer angefügten Eigenschaft über den Get-Methodenaccessor für diese Eigenschaft abfragt und dabei eine Instanz der Klasse angibt, in der Sie die Metadaten festgelegt haben, und der Wert für diese angefügte Eigenschaft nicht auf andere Weise festgelegt wurde.

Wenn Sie für eine Eigenschaft die Vererbung von Eigenschaftswerten aktivieren möchten, sollten Sie anstelle von nicht angefügten Abhängigkeitseigenschaften angefügte Eigenschaften verwenden. Ausführliche Informationen finden Sie unter Vererbung von Eigenschaftswerten.

Benutzerdefinierte angefügte Eigenschaften

Wann wird eine angefügte Eigenschaft erstellt?

Sie können eine angefügte Eigenschaft erstellen, wenn es erforderlich ist, einen Mechanismus zum Festlegen von Eigenschaften für andere Klassen als die definierende Klasse bereitzustellen. Am häufigsten werden für dieses Szenario die Layoutfunktionen verwendet. Beispiele für vorhandene Layouteigenschaften sind DockPanel.Dock, Panel.ZIndex und Canvas.Top. Bei diesem Szenario sind Elemente, die als untergeordnete Elemente von Elementen der Layoutsteuerung vorhanden sind, dazu in der Lage, Layoutanforderungen einzeln für ihre übergeordneten Layoutelemente auszudrücken. Die Elemente legen jeweils einen Eigenschaftswert fest, den das übergeordnete Element als angefügte Eigenschaft definiert hat.

Ein anderes Szenario der Verwendung einer angefügten Eigenschaft ist, wenn Ihre Klasse einen Dienst darstellt und Sie möchten, dass Klassen den Dienst auf transparentere Weise integrieren können.

Ein weiteres Szenario ist die Visual Studio 2008-WPF-Designer-Unterstützung, zum Beispiel die Bearbeitung im Fenster Eigenschaften. Weitere Informationen finden Sie unter Übersicht über das Erstellen von Steuerelementen.

Wie bereits erwähnt, sollten Sie die Registrierung als angefügte Eigenschaft durchführen, wenn Sie die Vererbung von Eigenschaftswerten verwenden möchten.

Erstellen einer angefügten Eigenschaft

Wenn Ihre Klasse die angefügte Eigenschaft nur für die Verwendung auf anderen Typen definiert, muss die Klasse keine Ableitung von DependencyObject durchführen. Die Ableitung von DependencyObject ist jedoch erforderlich, wenn Sie sich an das allgemeine WPF-Modell halten, das besagt, dass es sich bei der angefügten Eigenschaft auch um eine Abhängigkeitseigenschaft handeln soll.

Definieren Sie die angefügte Eigenschaft als Abhängigkeitseigenschaft, indem Sie ein public static readonly-Feld vom Typ DependencyProperty deklarieren. Sie definieren dieses Feld, indem Sie den Rückgabewert der RegisterAttached-Methode verwenden. Der Feldname muss mit dem Namen der angefügten Eigenschaft übereinstimmen, dem die Zeichenfolge Property angehängt wird, um das gängige WPF-Muster für die Benennung der identifizierenden Felder und der zugrunde liegenden Eigenschaften einzuhalten. Der Provider der angefügten Eigenschaft muss auch die statischen Methoden GetPropertyName und SetPropertyName als Accessoren für die angefügte Eigenschaft bereitstellen. Ist dies nicht der Fall, kann das Eigenschaftensystem Ihre angefügte Eigenschaft nicht verwenden.

HinweisHinweis

Wenn Sie den get-Accessor der angefügten Eigenschaft ausschließen, funktioniert die Datenbindung für die Eigenschaft nicht in Entwurfstools wie Visual Studio und Expression Blend.

get-Accessor

Die Signatur für den GetPropertyName-Accessor muss wie folgt lauten:

public static object GetPropertyName(object target)

  • Das target-Objekt kann in der Implementierung als spezifischerer Typ angegeben werden. Die DockPanel.GetDock-Methode verwendet den Parameter zum Beispiel in der Form UIElement, da die angefügte Eigenschaft nur für die Festlegung für UIElement-Instanzen vorgesehen ist.

  • Der Rückgabewert kann in der Implementierung als spezifischerer Typ angegeben werden. Die GetDock-Methode verwendet zum Beispiel die Form Dock, da der Wert nur für diese Enumeration festgelegt werden kann.

set-Accessor

Die Signatur für den SetPropertyName-Accessor muss wie folgt lauten:

public static void SetPropertyName(object target, object value)

  • Das target-Objekt kann in der Implementierung als spezifischerer Typ angegeben werden. Die SetDock-Methode verwendet zum Beispiel die Form UIElement, da die angefügte Eigenschaft nur für die Festlegung für UIElement-Instanzen vorgesehen ist.

  • Das value-Objekt kann in der Implementierung als spezifischerer Typ angegeben werden. Die SetDock-Methode verwendet zum Beispiel die Form Dock, da der Wert nur für diese Enumeration festgelegt werden kann. Denken Sie daran, dass der Wert für diese Methode die Eingabe ist, die vom XAML-Ladeprogramm stammt, wenn dieses Ihre angefügte Eigenschaft bei Verwendung in Markup erkennt. Diese Eingabe ist der Wert, der als XAML-Attributwert in Markup angegeben ist. Aus diesem Grund muss für den verwendeten Typ Unterstützung für die Typkonvertierung, ein Wertserialisierungsprogramm oder die Markuperweiterung vorhanden sein, damit aus dem Attributwert (eigentlich nur eine Zeichenfolge) der jeweils erforderliche Typ erstellt werden kann.

Das folgende Beispiel zeigt die Registrierung der Abhängigkeitseigenschaft (mithilfe der RegisterAttached-Methode) sowie die Accessoren GetPropertyName und SetPropertyName. Im Beispiel lautet der Name der angefügten Eigenschaft IsBubbleSource. Deshalb müssen die Accessoren GetIsBubbleSource und SetIsBubbleSource genannt werden.

Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
    element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
    Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}

Attribute von angefügten Eigenschaften

WPF definiert mehrere .NET Framework attributes-Elemente, mit deren Hilfe für Reflektionsprozesse und typische Nutzer von Reflektions- und Eigenschaftendaten Informationen zu angefügten Eigenschaften bereitgestellt werden sollen. Da angefügte Eigenschaften über einen Typ mit unbegrenztem Umfang verfügen, müssen Entwickler verhindern, Benutzer mit einer globalen Liste aller angefügten Eigenschaften zu verwirren, die in einer bestimmten Technologieimplementierung mit XAML-Verwendung definiert sind. Sie können die .NET Framework attributes-Elemente, die WPF für angefügte Eigenschaften definiert, verwenden, um den Umfang für Situationen festzulegen, in denen eine bestimmte angefügte Eigenschaft in einem Eigenschaftenfenster angezeigt werden soll. Sie können es in Betracht ziehen, diese Attribute auch für Ihre eigenen benutzerdefinierten angefügten Eigenschaften anzuwenden. Der Zweck und die Syntax von .NET Framework attributes sind auf den entsprechenden Verweisseiten beschrieben:

Weitere Informationen – Angefügte Eigenschaften

  • Weitere Informationen zur Erstellung einer angefügten Eigenschaft finden Sie unter Gewusst wie: Registrieren einer angefügten Eigenschaft.

  • Weitergehende Nutzungsszenarios für Abhängigkeitseigenschaften und angefügte Eigenschaften finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.

  • Sie können eine Eigenschaft auch als angefügte Eigenschaft und als Abhängigkeitseigenschaft registrieren, dann jedoch trotzdem Wrapperimplementierungen offenlegen. In diesem Fall können Sie die Eigenschaft entweder für das entsprechende Element oder ein beliebiges anderes Element festlegen, indem Sie die XAML-Syntax für angefügte Eigenschaften verwenden. Ein Beispiel für eine Eigenschaft mit einem entsprechenden Szenario für die standardmäßige und die angefügte Nutzung ist FrameworkElement.FlowDirection.

Siehe auch

Aufgaben

Gewusst wie: Registrieren einer angefügten Eigenschaft

Referenz

DependencyProperty

Konzepte

Übersicht über Abhängigkeitseigenschaften

Benutzerdefinierte Abhängigkeitseigenschaften

Übersicht über XAML (WPF)