Freigeben über


Übersicht über angehängte Eigenschaften

Eine angefügte Eigenschaft ist ein XAML-Konzept (Extensible Application Markup Language). Angefügte Eigenschaften ermöglichen es, zusätzliche Eigenschafts-Wert-Paare für alle XAML-Elemente festzulegen, die von DependencyObject abgeleitet sind, auch wenn das Element diese zusätzlichen Eigenschaften nicht in seinem Objektmodell definiert. Auf die zusätzlichen Eigenschaften kann global zugegriffen werden. Angefügte Eigenschaften werden in der Regel als spezielle Form von Abhängigkeitseigenschaft definiert, die nicht über einen herkömmlichen Eigenschaftenwrapper verfügt.

Voraussetzungen

In diesem Artikel wird davon ausgegangen, dass Sie über grundlegende Kenntnisse von Abhängigkeitseigenschaften verfügen und eine Übersicht über Abhängigkeitseigenschaften gelesen haben. Um den Beispielen in diesem Artikel zu folgen, hilft es Ihnen, wenn Sie mit XAML vertraut sind und wissen, wie Sie Windows Presentation Foundation (WPF)-Anwendungen schreiben.

Gründe für die Verwendung angefügter Eigenschaften

Mit einer angefügten Eigenschaft kann ein untergeordnetes Element einen eindeutigen Wert für eine Eigenschaft angeben, die in einem übergeordneten Element definiert ist. Ein gängiges Szenario ist ein untergeordnetes Element, das angibt, wie es in der Benutzeroberfläche durch das übergeordnete Element gerendert werden soll. Zum Beispiel ist DockPanel.Dock eine angefügte Eigenschaft, da sie für untergeordnete Elemente eines DockPanel, aber nicht für DockPanel selbst festgelegt ist. Die DockPanel Klasse definiert ein statisches DependencyProperty Feld mit dem Namen DockPropertyund stellt GetDockSetDock dann Methoden als öffentliche Accessoren für die angefügte Eigenschaft bereit.

Angefügte Eigenschaften in XAML

In XAML legen Sie angefügte Eigenschaften mithilfe der Syntax <attached property provider type>.<property name>fest, wobei der Anbieter der angefügten Eigenschaft die Klasse ist, die die angefügte Eigenschaft definiert. Das folgende Beispiel zeigt, wie ein untergeordnetes Element von DockPanel den DockPanel.Dock-Eigenschaftswert festlegen kann.

<DockPanel>
    <TextBox DockPanel.Dock="Top">Enter text</TextBox>
</DockPanel>

Die Verwendung ähnelt einer statischen Eigenschaft, indem Sie auf den Typ verweisen, der die angefügte Eigenschaft besitzt und registriert, zum Beispiel DockPanel, nicht den Namen der Instanz.

Wenn Sie eine angefügte Eigenschaft mithilfe eines XAML-Attributs angeben, gilt nur die Set-Aktion. Sie können einen Eigenschaftswert nicht direkt über XAML abrufen, obwohl es einige indirekte Mechanismen zum Vergleichen von Werten gibt, z. B. Trigger in Formatvorlagen.

Angefügte Eigenschaften in WPF

Angefügte Eigenschaften sind ein XAML-Konzept, Abhängigkeitseigenschaften sind ein WPF-Konzept. In WPF werden die meisten benutzeroberflächebezogenen angefügten Eigenschaften für WPF-Typen als Abhängigkeitseigenschaften implementiert. Angefügte WPF-Eigenschaften, die als Abhängigkeitseigenschaften implementiert werden, unterstützen Abhängigkeitseigenschaftenkonzepte, z. B. Eigenschaftsmetadaten, einschließlich Standardwerte aus Metadaten.

Verwendungsmodelle für angefügte Eigenschaften

Obwohl jedes Objekt einen angefügten Eigenschaftswert festlegen kann, bedeutet dies nicht, dass das Festlegen eines Werts ein greifbares Ergebnis erzeugt oder der Wert von einem anderen Objekt verwendet wird. Der Hauptzweck angefügter Eigenschaften besteht darin, Objekten aus einer Vielzahl von Klassenhierarchien und logischen Beziehungen eine Möglichkeit bereitzustellen, allgemeine Informationen an den Typ zu melden, der die angefügte Eigenschaft definiert. Die Verwendung angefügter Eigenschaften folgt in der Regel einem der folgenden Modelle:

  • Der Typ, der die angefügte Eigenschaft definiert, ist das übergeordnete Element der Elemente, die Werte für die angefügte Eigenschaft festlegen. Das Elternobjekt durchläuft seine untergeordneten Objekte mittels interner Logik, die auf die Baumstruktur wirkt, die Werte abruft und diese Werte auf irgendeine Weise auswertet.
  • Der Typ, der die angefügte Eigenschaft definiert, wird als Kind-Element in verschiedenen möglichen übergeordneten Elementen und Inhaltsmodellen 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 dann das Element, das die Eigenschaft festgelegt hat, im Kontext des Diensts ausgewertet wird, werden die Werte der angefügten Eigenschaft über die interne Logik der Dienstklasse abgerufen.

Ein Beispiel für eine übergeordnete angefügte Eigenschaft

Das typische Szenario, in dem WPF eine angefügte Eigenschaft definiert, besteht darin, dass ein übergeordnetes Element eine untergeordnete Elementauflistung unterstützt, und das übergeordnete Element implementiert ein Verhalten basierend auf den von den einzelnen untergeordneten Elementen gemeldeten Daten.

DockPanel definiert die DockPanel.Dock angefügte Eigenschaft. DockPanel verfügt über Code auf Klassenebene, insbesondere MeasureOverride und ArrangeOverridedies ist Teil der Renderinglogik. Eine DockPanel Instanz überprüft, ob eines ihrer unmittelbaren Kinderelemente einen Wert für DockPanel.Dock festgelegt hat. Wenn ja, werden diese Werte zu Eingaben für die Renderinglogik, die auf jedes untergeordnete Element angewendet wird. Obwohl es theoretisch möglich ist, dass angefügte Eigenschaften Elemente beeinflussen, die über das unmittelbare übergeordnete Element hinausgehen, besteht das definierte Verhalten für eine geschachtelte DockPanel-Instanz darin, nur mit der unmittelbaren Sammlung untergeordneter Elemente zu interagieren. Wenn Sie also ein DockPanel.Dock für ein Element festlegen, das kein übergeordnetes DockPanel aufweist, wird kein Fehler oder keine Ausnahme ausgelöst, und Sie hätten einen globalen Eigenschaftswert erstellt, der von keinem DockPanel verwendet wird.

Angefügte Eigenschaften im Code

Angefügte Eigenschaften in WPF verfügen nicht über die typischen CLR get - und set Wrappermethoden, da die Eigenschaften möglicherweise außerhalb des CLR-Namespace festgelegt werden. Damit ein XAML-Prozessor diese Werte beim Parsen von XAML festsetzen kann, muss die Klasse, die die angefügte Eigenschaft definiert, spezielle Accessormethoden in Form von Get<property name> und Set<property name> implementieren.

Sie können auch die dedizierten Accessormethoden verwenden, um eine angefügte Eigenschaft im Code abzurufen und festzulegen, wie im folgenden Beispiel gezeigt. Im Beispiel myTextBox ist eine Instanz der TextBox Klasse.

DockPanel myDockPanel = new();
TextBox myTextBox = new();
myTextBox.Text = "Enter text";

// Add child element to the DockPanel.
myDockPanel.Children.Add(myTextBox);

// Set the attached property value.
DockPanel.SetDock(myTextBox, Dock.Top);
Dim myDockPanel As DockPanel = New DockPanel()
Dim myTextBox As TextBox = New TextBox()
myTextBox.Text = "Enter text"

' Add child element to the DockPanel.
myDockPanel.Children.Add(myTextBox)

' Set the attached property value.
DockPanel.SetDock(myTextBox, Dock.Top)

Wenn Sie myTextBox nicht als untergeordnetes Element von myDockPanel hinzufügen, löst der Aufruf SetDock keine Ausnahme aus und hat keine Wirkung. Nur ein DockPanel.Dock Wert, der für ein untergeordnetes Element eines DockPanel-Elements festgelegt wird, kann sich auf das Rendern auswirken, und das Rendering ist identisch, unabhängig davon, ob Sie den Wert vor oder nach dem Hinzufügen des untergeordneten Elements zum DockPanel-Element festlegen.

Aus Programmiersicht ist eine angefügte Eigenschaft wie ein Hintergrundfeld mit Methodenzugriffen anstelle von Eigenschaftszugriffen und kann für jedes Objekt festgelegt werden, ohne vorher auf diesen Objekten definiert zu sein.

Metadaten der angefügten Eigenschaft

Metadaten für eine angefügte Eigenschaft unterscheiden sich in der Regel nicht von einer Abhängigkeitseigenschaft. Verwenden Sie FrameworkPropertyMetadata, um beim Registrieren einer angefügten Eigenschaft Merkmale der Eigenschaft festzulegen, z. B. ob sich die Eigenschaft auf das Rendering oder die Messung auswirkt. Wenn Sie einen Standardwert angeben, indem Sie angefügte Eigenschaftsmetadaten überschreiben, wird dieser Wert zur Standardeinstellung für die implizite angefügte Eigenschaft für Instanzen der überschreibenden Klasse. Wenn kein angefügter Eigenschaftswert andernfalls festgelegt wird, wird der Standardwert gemeldet, wenn die Eigenschaft mithilfe des Get<property name> Accessors mit einer Instanz der Klasse abgefragt wird, in der Sie die Metadaten angegeben haben.

Verwenden Sie angefügte Eigenschaften anstelle von nicht angefügten Abhängigkeitseigenschaften, um die Eigenschaftswertvererbung für eine Eigenschaft zu aktivieren. Weitere Informationen finden Sie unter Eigenschaftswertvererbung.

Benutzerdefinierte angefügte Eigenschaften

Wann eine angefügte Eigenschaft erstellt werden soll

Das Erstellen einer angefügten Eigenschaft ist nützlich, wenn:

  • Sie benötigen einen Mechanismus zum Festlegen von Eigenschaften, der für andere Klassen als die definierende Klasse verfügbar ist. Ein häufiges Szenario ist das Layout einer Benutzeroberfläche. Zum Beispiel sind DockPanel.Dock, Panel.ZIndex und Canvas.Top alles Beispiele für bestehende Layouteigenschaften. Im Layoutszenario können untergeordnete Elemente eines Layoutsteuerungselements Layoutanforderungen für das übergeordnete Layout ausdrücken und einen Wert für eine angefügte Eigenschaft festlegen, die vom übergeordneten Element definiert wird.

  • Eine Ihrer Klassen stellt einen Dienst dar, und Sie möchten, dass andere Klassen den Dienst transparenter integrieren.

  • Sie möchten Unterstützung für den Visual Studio WPF-Designer, wie zum Beispiel die Möglichkeit, eine Eigenschaft über das Eigenschaftenfenster zu bearbeiten. Weitere Informationen finden Sie unter Übersicht über die Steuerelementerstellung

  • Sie möchten die Eigenschaftswertvererbung verwenden.

Erstellen einer angefügten Eigenschaft

Wenn Ihre Klasse eine angefügte Eigenschaft ausschließlich für die Verwendung durch andere Typen definiert, muss Ihre Klasse nicht von DependencyObject. Folgen Sie andernfalls dem WPF-Modell, indem eine angefügte Eigenschaft auch als Abhängigkeitseigenschaft fungiert, indem Sie die Klasse von DependencyObject ableiten.

Definieren Sie die angefügte Eigenschaft als Abhängigkeit in der definierenden Klasse, indem Sie ein public static readonly Feld vom Typ DependencyPropertydeklarieren. Weisen Sie dann dem Feld den Rückgabewert der RegisterAttached Methode zu, der auch als Abhängigkeitseigenschaftsbezeichner bezeichnet wird. Folgen Sie der WPF-Eigenschaftsbenennungskonvention, die Felder von den eigenschaften unterscheidet, die sie darstellen, indem Sie das Bezeichnerfeld <property name>Propertybenennen. Stellen Sie außerdem statische Get<property name> und Set<property name> accessor-Methoden bereit, mit denen das Eigenschaftensystem auf Ihre angefügte Eigenschaft zugreifen kann.

Das folgende Beispiel zeigt, wie sie eine Abhängigkeitseigenschaft mithilfe der RegisterAttached Methode registrieren und wie die Accessormethoden definiert werden. Im Beispiel lautet der Name der angefügten Eigenschaft HasFish, daher wird das Identifikatorfeld HasFishProperty genannt, und die Accessor-Methoden heißen GetHasFish und SetHasFish.

public class Aquarium : UIElement
{
    // Register an attached dependency property with the specified
    // property name, property type, owner type, and property metadata.
    public static readonly DependencyProperty HasFishProperty = 
        DependencyProperty.RegisterAttached(
      "HasFish",
      typeof(bool),
      typeof(Aquarium),
      new FrameworkPropertyMetadata(defaultValue: false,
          flags: FrameworkPropertyMetadataOptions.AffectsRender)
    );

    // Declare a get accessor method.
    public static bool GetHasFish(UIElement target) =>
        (bool)target.GetValue(HasFishProperty);

    // Declare a set accessor method.
    public static void SetHasFish(UIElement target, bool value) =>
        target.SetValue(HasFishProperty, value);
}
Public Class Aquarium
    Inherits UIElement

    ' Register an attached dependency property with the specified
    ' property name, property type, owner type, and property metadata.
    Public Shared ReadOnly HasFishProperty As DependencyProperty =
        DependencyProperty.RegisterAttached("HasFish", GetType(Boolean), GetType(Aquarium),
            New FrameworkPropertyMetadata(defaultValue:=False,
                flags:=FrameworkPropertyMetadataOptions.AffectsRender))

    ' Declare a get accessor method.
    Public Shared Function GetHasFish(target As UIElement) As Boolean
        Return target.GetValue(HasFishProperty)
    End Function

    ' Declare a set accessor method.
    Public Shared Sub SetHasFish(target As UIElement, value As Boolean)
        target.SetValue(HasFishProperty, value)
    End Sub

End Class

Der Get-Accessor

Die get Accessor-Methodensignatur lautet public static object Get<property name>(DependencyObject target), wobei:

  • target ist die DependencyObject , von der die angefügte Eigenschaft gelesen wird. Der target Typ kann spezifischer sein als DependencyObject. Ein Beispiel: Die Accessormethode bezeichnet die target als UIElement, weil die angefügte Eigenschaft für UIElement-Instanzen bestimmt ist. UiElement wird indirekt von DependencyObject.
  • Der Rückgabetyp kann spezifischer sein als object. Die Methode typisiert beispielsweise den zurückgegebenen Wert als GetDock, weil der Rückgabewert eine Dock Enumeration sein soll.

Hinweis

Der get Accessor für eine angefügte Eigenschaft ist für die Unterstützung der Datenbindung in Entwurfstools wie Visual Studio oder Blend für Visual Studio erforderlich.

Der Set-Accessor

Die set Accessor-Methodensignatur lautet public static void Set<property name>(DependencyObject target, object value), wobei:

  • target ist die DependencyObject Eigenschaft, für die die angefügte Eigenschaft geschrieben wird. Der target Typ kann spezifischer sein als DependencyObject. Die Methode gibt z. B. folgendes UIElementtarget ein, SetDock weil die angefügte Eigenschaft für UIElement Instanzen festgelegt werden soll. UiElement wird indirekt von DependencyObject.
  • Der value Typ kann spezifischer sein als object. Die Methode erfordert zum Beispiel einen SetDock und einen Dock Wert. Das XAML-Ladeprogramm muss den value Typ aus der Markupzeichenfolge generieren können, die den Wert der angefügten Eigenschaft darstellt. Es muss also eine Typkonvertierung, ein Wertserialisierer oder eine Markup-Erweiterungsunterstützung für den von Ihnen verwendeten Typ geben.

Attribute der angefügten Eigenschaft

WPF definiert mehrere .NET-Attribute, die Informationen zu angefügten Eigenschaften für Spiegelungsprozesse und auch für Verbraucher von Spiegelungs- und Eigenschaftsinformationen, z. B. Designern, bereitstellen. Designer verwenden WPF-definierte .NET-Attribute, um die im Eigenschaftenfenster angezeigten Eigenschaften einzuschränken, um zu vermeiden, dass Benutzer mit einer globalen Liste aller zugeordneten Eigenschaften überwältigt werden. Sie könnten diese Attribute auf Ihre eigenen benutzerdefinierten Eigenschaften anwenden. Der Zweck und die Syntax von .NET-Attributen wird auf den folgenden Referenzseiten beschrieben:

Erfahren Sie mehr

  • Weitere Informationen zum Erstellen einer angefügten Eigenschaft finden Sie unter Registrieren einer angefügten Eigenschaft.
  • Weitere erweiterte Verwendungsszenarien für Abhängigkeitseigenschaften und angefügte Eigenschaften finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.
  • Sie können eine Eigenschaft sowohl als angefügte Eigenschaft als auch als Abhängigkeitseigenschaft registrieren und herkömmliche Eigenschaftenwrapper einschließen. Auf diese Weise kann eine Eigenschaft für ein Element mithilfe von Eigenschaftswrappern und auch für jedes andere Element mithilfe der XAML-Syntax angefügter Eigenschaften festgelegt werden. Ein Beispiel finden Sie unter FrameworkElement.FlowDirection.

Siehe auch