Benutzerdefinierte AbhängigkeitseigenschaftenCustom Dependency Properties

Dieses Thema beschreibt die Gründe, warum Anwendungsentwickler und Komponentenautoren in Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) benutzerdefinierte Abhängigkeitseigenschaften erstellen möchten, und beschreibt die Implementierungsmaßnahmen und -optionen, die die Leistung, Verwendbarkeit oder Vielseitigkeit der Eigenschaft verbessern können.This topic describes the reasons that Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) application developers and component authors might want to create custom dependency property, and describes the implementation steps as well as some implementation options that can improve performance, usability, or versatility of the property.

Erforderliche KomponentenPrerequisites

In diesem Thema wird vorausgesetzt, dass Sie sich mit Abhängigkeitseigenschaften aus Sicht von vorhandenen Abhängigkeitseigenschaften von Consumern in WPFWPF-Klassen auskennen, und dass Sie das Thema Übersicht über Abhängigkeitseigenschaften gelesen haben.This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on WPFWPF classes, and have read the Dependency Properties Overview topic. Um den Beispielen in diesem Thema zu folgen, sollten Sie zudem mit Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) vertraut sein und wissen, wie WPFWPF-Anwendungen geschrieben werden.In order to follow the examples in this topic, you should also understand Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) and know how to write WPFWPF applications.

Was ist eine Abhängigkeitseigenschaft?What Is a Dependency Property?

Sie können aktivieren, was andernfalls eine Common Language Runtime (CLR)-Eigenschaft wäre, um Formatierung, Datenbindung, Vererbung, Animationen und Standardwerte zu unterstützen, indem Sie Sie als Abhängigkeits Eigenschaft implementieren.You can enable what would otherwise be a common language runtime (CLR) property to support styling, data binding, inheritance, animations, and default values by implementing it as a dependency property. Abhängigkeits Eigenschaften sind WPFWPF Eigenschaften, die beim-Eigenschaften System durch Aufrufen der Register -Methode (oder RegisterReadOnly) registriert sind und durch ein DependencyProperty Bezeichnerfeld unterstützt werden.Dependency properties are properties that are registered with the WPFWPF property system by calling the Register method (or RegisterReadOnly), and that are backed by a DependencyProperty identifier field. Abhängigkeits Eigenschaften können nur DependencyObject von-Typen verwendet werden DependencyObject , sind jedoch in der WPFWPF Klassenhierarchie sehr hoch, sodass die Mehrzahl der in WPFWPF verfügbaren Klassen Abhängigkeits Eigenschaften unterstützen können.Dependency properties can be used only by DependencyObject types, but DependencyObject is quite high in the WPFWPF class hierarchy, so the majority of classes available in WPFWPF can support dependency properties. Weitere Informationen zu Abhängigkeitseigenschaften und zur Terminologie und den Konventionen für die Beschreibung in SDKSDK finden Sie unter Übersicht über Abhängigkeitseigenschaften.For more information about dependency properties and some of the terminology and conventions used for describing them in this SDKSDK, see Dependency Properties Overview.

Beispiele für AbhängigkeitseigenschaftenExamples of Dependency Properties

Beispiele für Abhängigkeits Eigenschaften, die für WPFWPF -Klassen implementiert Background werden, sind u. a. Text die-Eigenschaft, die Width -Eigenschaft und die-Eigenschaft.Examples of dependency properties that are implemented on WPFWPF classes include the Background property, the Width property, and the Text property, among many others. Jede Abhängigkeits Eigenschaft, die von einer Klasse verfügbar gemacht wird, verfügt über DependencyProperty ein entsprechendes öffentliches statisches Feld vom Typ, das für die gleiche KlasseEach dependency property exposed by a class has a corresponding public static field of type DependencyProperty exposed on that same class. Es handelt sich um den Bezeichner für die Abhängigkeitseigenschaft.This is the identifier for the dependency property. Der Name des Bezeichners wird nach einer Konvention gewählt: Der Name der Abhängigkeitseigenschaft mit der angefügten Zeichenfolge Property.The identifier is named using a convention: the name of the dependency property with the string Property appended to it. Beispielsweise ist DependencyProperty Background dasentsprechendeBezeichnerfeldfürBackgroundPropertydie-Eigenschaft.For example, the corresponding DependencyProperty identifier field for the Background property is BackgroundProperty. Der Bezeichner speichert die Informationen zur Abhängigkeits Eigenschaft, während er registriert wurde. der Bezeichner wird dann später für andere Vorgänge verwendet, die die Abhängigkeits Eigenschaft SetValuebetreffen, z. b. durch Aufrufen von.The identifier stores the information about the dependency property as it was registered, and the identifier is then used later for other operations involving the dependency property, such as calling SetValue.

Wie in der Übersicht über Abhängigkeits Eigenschaftenerwähnt, sind alle WPFWPF Abhängigkeits Eigenschaften in (außer den meisten angefügten Eigenschaften) aufgrund der "Wrapper"-Implementierung auch CLR-Eigenschaften.As mentioned in the Dependency Properties Overview, all dependency properties in WPFWPF (except most attached properties) are also CLR properties because of the "wrapper" implementation. Aus dem Code können Sie daher Abhängigkeits Eigenschaften abrufen oder festlegen, indem Sie CLR-Accessoren aufrufen, die die Wrapper auf die gleiche Weise definieren, wie Sie andere CLR-Eigenschaften verwenden würden.Therefore, from code, you can get or set dependency properties by calling CLR accessors that define the wrappers in the same manner that you would use other CLR properties. Als Consumer von festgelegten Abhängigkeits Eigenschaften verwenden Sie in der Regel nicht DependencyObject die GetValue Methoden SetValueund, die den Verbindungspunkt zum zugrunde liegenden Eigenschaften System sind.As a consumer of established dependency properties, you do not typically use the DependencyObject methods GetValue and SetValue, which are the connection point to the underlying property system. Stattdessen hat die vorhandene Implementierung der CLR-Eigenschaften bereits und GetValue SetValue in den get -und-Wrapper set Implementierungen der-Eigenschaft aufgerufen, wobei das Bezeichnerfeld entsprechend verwendet wird.Rather, the existing implementation of the CLR properties will have already called GetValue and SetValue within the get and set wrapper implementations of the property, using the identifier field appropriately. Wenn Sie eine benutzerdefinierte Abhängigkeitseigenschaft selbst implementieren, definieren Sie den Wrapper auf ähnliche Weise.If you are implementing a custom dependency property yourself, then you will be defining the wrapper in a similar way.

Wann sollten Sie eine Abhängigkeitseigenschaft implementieren?When Should You Implement a Dependency Property?

Wenn Sie eine Eigenschaft für eine Klasse implementieren, können Sie, solange die Klasse von DependencyObjectabgeleitet ist, die-Eigenschaft mit einem DependencyProperty -Bezeichner sichern und so eine Abhängigkeits Eigenschaft erstellen.When you implement a property on a class, so long as your class derives from DependencyObject, you have the option to back your property with a DependencyProperty identifier and thus to make it a dependency property. Es ist nicht immer notwendig oder angemessen, Ihre Eigenschaft in eine Abhängigkeitseigenschaft umzuwandeln. Es hängt von den Anforderungen Ihres Szenarios ab.Having your property be a dependency property is not always necessary or appropriate, and will depend on your scenario needs. Manchmal ist die normale Technik des Sicherns der Eigenschaft mit einem privaten Feld ausreichend.Sometimes, the typical technique of backing your property with a private field is adequate. Sie sollten Ihre Eigenschaft allerdings als Abhängigkeitseigenschaft implementieren, wenn Sie möchten, dass Ihre Eigenschaft eine oder mehrere der folgenden WPFWPF-Funktionen unterstützt:However, you should implement your property as a dependency property whenever you want your property to support one or more of the following WPFWPF capabilities:

  • Sie möchten, dass Ihre Eigenschaft in einem Stil festgelegt werden kann.You want your property to be settable in a style. Weitere Informationen finden Sie unter Erstellen von Formaten und Vorlagen.For more information, see Styling and Templating.

  • Sie möchten, dass die Eigenschaft Datenbindung unterstützt.You want your property to support data binding. Weitere Informationen zur Datenbindung mit Abhängigkeitseigenschaften finden Sie unter Binden der Eigenschaften von zwei Steuerelementen.For more information about data binding dependency properties, see Bind the Properties of Two Controls.

  • Sie möchten, dass die Eigenschaft mit einem dynamischen Ressourcenverweis festgelegt werden kann.You want your property to be settable with a dynamic resource reference. Weitere Informationen finden Sie unter XAML-Ressourcen.For more information, see XAML Resources.

  • Sie möchten einen Eigenschaftswert automatisch von einem übergeordneten Element in der Elementstruktur erben.You want to inherit a property value automatically from a parent element in the element tree. Registrieren Sie in diesem Fall mit der RegisterAttached -Methode, auch wenn Sie einen Eigenschafts Wrapper für den CLR-Zugriff erstellen.In this case, register with the RegisterAttached method, even if you also create a property wrapper for CLR access. Weitere Informationen finden Sie unter Vererbung von Eigenschaftswerten.For more information, see Property Value Inheritance.

  • Sie möchten, dass Ihre Eigenschaft animiert werden kann.You want your property to be animatable. Weitere Informationen finden Sie unter Übersicht über Animation.For more information, see Animation Overview.

  • Sie möchten, dass das Eigenschaftensystem berichtet, wenn der vorherige Wert der Eigenschaft durch Aktionen des Eigenschaftensystems, der Umgebung, des Benutzers oder durch Lesen und Verwenden von Stilen geändert wurde.You want the property system to report when the previous value of the property has been changed by actions taken by the property system, the environment, or the user, or by reading and using styles. Mithilfe von Eigenschaftenmetadaten kann Ihre Eigenschaft eine Rückrufmethode angeben, die jedes Mal aufgerufen wird, wenn das Eigenschaftensystem feststellt, dass der Eigenschaftswert eindeutig geändert wurde.By using property metadata, your property can specify a callback method that will be invoked each time the property system determines that your property value was definitively changed. Ein verwandtes Konzept ist die Koersion des Eigenschaftswerts.A related concept is property value coercion. Weitere Informationen finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften.For more information, see Dependency Property Callbacks and Validation.

  • Sie möchten geltende Konventionen für Metadaten verwenden, die auch von WPFWPF-Vorgängen verwendet werden, z.B. der Bericht, ob das Layoutsystem aufgrund eines geänderten Eigenschaftswerts die visuellen Objekte für ein Element neu aufbauen soll.You want to use established metadata conventions that are also used by WPFWPF processes, such as reporting whether changing a property value should require the layout system to recompose the visuals for an element. Oder Sie möchten Überschreibungen von Metadaten verwenden, sodass abgeleitete Klassen auf Metadaten basierende Eigenschaften, z.B. den Standardwert, ändern können.Or you want to be able to use metadata overrides so that derived classes can change metadata-based characteristics such as the default value.

  • Sie möchten, dass die Eigenschaften eines benutzerdefinierten Steuer Elements den Visual Studio WPF-Designer unterstützen, z. b. die Bearbeitung von Eigenschaften FensternYou want properties of a custom control to receive Visual Studio WPF Designer support, such as Properties window editing. Weitere Informationen finden Sie unter Übersicht über das Erstellen von Steuerelementen.For more information, see Control Authoring Overview.

Wenn Sie diese Szenarios untersuchen, sollten Sie auch bedenken, ob Sie Ihr Szenario erreichen können, indem Sie die Metadaten einer vorhandenen Abhängigkeitseigenschaft überschreiben, anstatt eine völlig neue Eigenschaft zu implementieren.When you examine these scenarios, you should also consider whether you can achieve your scenario by overriding the metadata of an existing dependency property, rather than implementing a completely new property. Ob die Überschreibung von Metadaten sinnvoll ist hängt von Ihrem Szenario ab und wie sehr dieses Szenario der Implementierung vorhandener WPFWPF-Abhängigkeitseigenschaften und -Klassen ähnelt.Whether a metadata override is practical depends on your scenario and how closely that scenario resembles the implementation in existing WPFWPF dependency properties and classes. Weitere Informationen zum Überschreiben der Metadaten von vorhandenen Eigenschaften finden Sie unter Metadaten für Abhängigkeitseigenschaften.For more information about overriding metadata on existing properties, see Dependency Property Metadata.

Prüfliste für die Definition einer AbhängigkeitseigenschaftChecklist for Defining a Dependency Property

Das Definieren einer Abhängigkeitseigenschaft besteht aus vier unterschiedlichen Konzepten.Defining a dependency property consists of four distinct concepts. Diese Konzepte sind nicht unbedingt aufeinanderfolgende Schritte, da einige von ihnen am Ende als einzelne Codezeilen in der Implementierung kombiniert werden:These concepts are not necessarily strict procedural steps, because some of these end up being combined as single lines of code in the implementation:

  • (Optional) Erstellen Sie Eigenschaftsmetadaten für die Abhängigkeitseigenschaft.(Optional) Create property metadata for the dependency property.

  • Registrieren Sie den Eigenschaftennamen im Eigenschaftensystem, indem Sie einen Besitzertyp und den Typ des Eigenschaftswerts angeben.Register the property name with the property system, specifying an owner type and the type of the property value. Geben Sie, falls verwendet, auch die Metadaten der Eigenschaft an.Also specify the property metadata, if used.

  • Definieren Sie DependencyProperty einen Bezeichner public static als Feldfürdenreadonly Besitzertyp.Define a DependencyProperty identifier as a public static readonly field on the owner type.

  • Definieren Sie eine CLR-Wrapper Eigenschaft, deren Name mit dem Namen der Abhängigkeits Eigenschaft übereinstimmt.Define a CLR "wrapper" property whose name matches the name of the dependency property. Implementieren Sie die-und get set -Accessoren der CLR "Wrapper"-Eigenschaft, um eine Verbindung mit der Abhängigkeits Eigenschaft herzustellen, die diese sichertImplement the CLR "wrapper" property's get and set accessors to connect with the dependency property that backs it.

Registrieren der Eigenschaft im EigenschaftensystemRegistering the Property with the Property System

Damit Ihre Eigenschaft zu einer Abhängigkeitseigenschaft wird, müssen Sie diese Eigenschaft in einer Tabelle im Eigenschaftensystem registrieren und einen eindeutigen Bezeichner angeben. Dieser wird als Qualifizierer für spätere Vorgänge im Eigenschaftensystem verwendet.In order for your property to be a dependency property, you must register that property into a table maintained by the property system, and give it a unique identifier that is used as the qualifier for later property system operations. Bei diesen Vorgängen kann es sich um interne Vorgänge oder ihren eigenen Code handeln, der die Eigenschaften System-APIs aufrufenThese operations might be internal operations, or your own code calling property system APIs. Um die Eigenschaft zu registrieren, müssen Sie Register die-Methode im Textkörper der Klasse (innerhalb der-Klasse, aber außerhalb von Element Definitionen) aufzurufen.To register the property, you call the Register method within the body of your class (inside the class, but outside of any member definitions). Das Bezeichnerfeld wird auch vom Register Methoden aufrufswert als Rückgabewert bereitgestellt.The identifier field is also provided by the Register method call, as the return value. Der Grund für die Register Ausführung des Aufrufes außerhalb anderer Element Definitionen ist, dass Sie diesen Rückgabewert verwenden, um ein public static readonly Feld vom Typ DependencyProperty als Teil der Klasse zuzuweisen und zu erstellen.The reason that the Register call is done outside of other member definitions is because you use this return value to assign and create a public static readonly field of type DependencyProperty as part of your class. Das Feld wird zum Bezeichner für Ihre Abhängigkeitseigenschaft.This field becomes the identifier for your dependency property.

public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
  "AquariumGraphic",
  typeof(Uri),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(null,
      FrameworkPropertyMetadataOptions.AffectsRender, 
      new PropertyChangedCallback(OnUriChanged)
  )
);
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty = DependencyProperty.Register("AquariumGraphic", GetType(Uri), GetType(AquariumObject), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf OnUriChanged)))

Namenskonventionen für AbhängigkeitseigenschaftenDependency Property Name Conventions

Es gibt Namenskonventionen für Abhängigkeitseigenschaften, die Sie bis auf bestimmte Ausnahmefälle befolgen müssen.There are established naming conventions regarding dependency properties that you must follow in all but exceptional circumstances.

Die Abhängigkeits Eigenschaft selbst hat einen einfachen Namen, "aquariengraphic", wie in diesem Beispiel, der als erster Parameter von Registerangegeben wird.The dependency property itself will have a basic name, "AquariumGraphic" as in this example, which is given as the first parameter of Register. Dieser Name muss innerhalb jedes Registrierungstyps eindeutig sein.That name must be unique within each registering type. Abhängigkeitseigenschaften, die über Basistypen geerbt werden, gelten bereits als teil des Registrierungstyps. Namen von geerbten Eigenschaften können nicht erneut registriert werden.Dependency properties inherited through base types are considered to be already part of the registering type; names of inherited properties cannot be registered again. Es gibt jedoch ein Verfahren zum Hinzufügen von Klassen als Besitzer einer Abhängigkeitseigenschaft, sogar wenn diese Abhängigkeitseigenschaft nicht geerbt ist. Weitere Informationen hierzu finden Sie unter Metadaten für Abhängigkeitseigenschaften.However, there is a technique for adding a class as owner of a dependency property even when that dependency property is not inherited; for details, see Dependency Property Metadata.

Geben Sie einem Bezeichnerfeld beim Erstellen den Namen der Eigenschaft bei der Registrierung und das Suffix Property.When you create the identifier field, name this field by the name of the property as you registered it, plus the suffix Property. Dieses Feld ist der Bezeichner für die-Abhängigkeits Eigenschaft und wird später als Eingabe für den SetValue -Aufruf und den- GetValue Aufruf verwendet, den Sie in den Wrappern durch jeglichen anderen Code Zugriff auf die Eigenschaft durch ihren eigenen Code, durch jeglichen externen Code Zugriff, den Sie zulassen, vornehmen. , vom-Eigenschaften System und potenziell von XAMLXAML Prozessoren.This field is your identifier for the dependency property, and it will be used later as an input for the SetValue and GetValue calls you will make in the wrappers, by any other code access to the property by your own code, by any external code access you allow, by the property system, and potentially by XAMLXAML processors.

Hinweis

Die übliche Implementierung ist das Definieren der Abhängigkeitseigenschaft im Text einer Klasse. Es ist aber auch möglich, eine Abhängigkeitseigenschaft im statischen Konstruktor der Klasse zu definieren.Defining the dependency property in the class body is the typical implementation, but it is also possible to define a dependency property in the class static constructor. Diese Vorgehensweise kann sinnvoll sein, wenn Sie mehr als eine Codezeile benötigen, um die Abhängigkeitseigenschaft zu initialisieren.This approach might make sense if you need more than one line of code to initialize the dependency property.

Implementieren des „Wrappers“Implementing the "Wrapper"

Die Wrapper Implementierung sollte in GetValue der get -Implementierung und in SetValue der set -Implementierung (der ursprüngliche Registrierungs Name und das-Feld werden ebenfalls zur Verdeutlichung angezeigt) aufgerufen werden.Your wrapper implementation should call GetValue in the get implementation, and SetValue in the set implementation (the original registration call and field are shown here too for clarity).

In allen außer Ausnahmefällen sollten Ihre Wrapper Implementierungen nur die GetValue Aktionen und SetValue ausführen.In all but exceptional circumstances, your wrapper implementations should perform only the GetValue and SetValue actions, respectively. Der Grund hierfür wird im Thema Laden von XAML und Abhängigkeitseigenschaften erläutert.The reason for this is discussed in the topic XAML Loading and Dependency Properties.

Alle vorhandenen öffentlichen Abhängigkeitseigenschaften, die für die WPFWPF-Klassen zur Verfügung stehen, verwenden dieses einfache Modell der Wrapper-Implementierung. Ein Großteil der komplexen Funktionsweise von Abhängigkeitseigenschaften ist entweder ein grundsätzliches Verhalten des Eigenschaftensystems oder wird durch andere Konzepte wie Koersion oder Rückrufe für Eigenschaftenänderungen durch Eigenschaftenmetadaten implementiert.All existing public dependency properties that are provided on the WPFWPF classes use this simple wrapper implementation model; most of the complexity of how dependency properties work is either inherently a behavior of the property system, or is implemented through other concepts such as coercion or property change callbacks through property metadata.


public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
  "AquariumGraphic",
  typeof(Uri),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(null,
      FrameworkPropertyMetadataOptions.AffectsRender, 
      new PropertyChangedCallback(OnUriChanged)
  )
);
public Uri AquariumGraphic
{
  get { return (Uri)GetValue(AquariumGraphicProperty); }
  set { SetValue(AquariumGraphicProperty, value); }
}

Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty = DependencyProperty.Register("AquariumGraphic", GetType(Uri), GetType(AquariumObject), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.AffectsRender, New PropertyChangedCallback(AddressOf OnUriChanged)))
Public Property AquariumGraphic() As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set(ByVal value As Uri)
        SetValue(AquariumGraphicProperty, value)
    End Set
End Property

Der Name der Wrapper Eigenschaft muss gemäß der Konvention mit dem ausgewählten Namen identisch sein und als erster Parameter des Register Aufrufes angegeben werden, der die Eigenschaft registriert hat.Again, by convention, the name of the wrapper property must be the same as the name chosen and given as first parameter of the Register call that registered the property. Wenn die Eigenschaft den Konventionen nicht folgt, werden dadurch nicht unbedingt alle möglichen Verwendungsarten deaktiviert, aber Sie werden mehrere deutliche Probleme bemerken:If your property does not follow the convention, this does not necessarily disable all possible uses, but you will encounter several notable issues:

  • Bestimmte Aspekte von Stilen und Vorlagen funktionieren nicht.Certain aspects of styles and templates will not work.

  • Die meisten Tools und Designer verlassen sich auf Benennungskonventionen, um XAMLXAML ordnungsgemäß zu serialisieren oder um Unterstützung für eine Entwicklerumgebung auf Ebene einzelner Eigenschaften zu bieten.Most tools and designers must rely on the naming conventions to properly serialize XAMLXAML, or to provide designer environment assistance at a per-property level.

  • Die aktuelle Implementierung des WPFWPF XAMLXAML-Ladeprogramms umgeht die Wrapper komplett und verlässt sich beim Verarbeiten von Attributwerten auf die Benennungskonvention.The current implementation of the WPFWPF XAMLXAML loader bypasses the wrappers entirely, and relies on the naming convention when processing attribute values. Weitere Informationen finden Sie unter Laden von XAML und Abhängigkeitseigenschaften.For more information, see XAML Loading and Dependency Properties.

Eigenschaftsmetadaten für eine neue AbhängigkeitseigenschaftProperty Metadata for a New Dependency Property

Wenn Sie eine Abhängigkeitseigenschaft registrieren, wird bei der Registrierung über das Eigenschaftensystem ein Metadatenobjekt erstellt, das Merkmale der Eigenschaft speichert.When you register a dependency property, the registration through the property system creates a metadata object that stores property characteristics. Viele dieser Eigenschaften verfügen über Standardwerte, die festgelegt werden, wenn die-Eigenschaft mit den Registereinfachen Signaturen von registriert wird.Many of these characteristics have defaults that are set if the property is registered with the simple signatures of Register. Andere Signaturen von Register ermöglichen es Ihnen, die Metadaten anzugeben, die Sie bei der Registrierung der Eigenschaft wünschen.Other signatures of Register allow you to specify the metadata that you want as you register the property. Die häufigste Art von Metadaten für Abhängigkeitseigenschaften ist ein Standardwert, der für jede neue Instanz angegeben wird, die diese Eigenschaft verwendet.The most common metadata given for dependency properties is to give them a default value that is applied on new instances that use the property.

Wenn Sie eine Abhängigkeits Eigenschaft erstellen, die auf einer abgeleiteten Klasse FrameworkElementvon vorhanden ist, können Sie anstelle der Basis FrameworkPropertyMetadata PropertyMetadata Klasse die speziellere Metadatenklasse verwenden.If you are creating a dependency property that exists on a derived class of FrameworkElement, you can use the more specialized metadata class FrameworkPropertyMetadata rather than the base PropertyMetadata class. Der Konstruktor für die FrameworkPropertyMetadata -Klasse verfügt über mehrere Signaturen, in denen Sie verschiedene Metadatenmerkmale in Kombination angeben können.The constructor for the FrameworkPropertyMetadata class has several signatures where you can specify various metadata characteristics in combination. Wenn Sie nur den Standardwert angeben möchten, verwenden Sie die Signatur, die einen einzelnen Parameter vom Typ Objectannimmt.If you want to specify the default value only, use the signature that takes a single parameter of type Object. Übergeben Sie diesen Objekt Parameter als typspezifischen Standardwert für die propertyType Register -Eigenschaft (der angegebene Standardwert muss der Typ sein, den Sie im-Befehl als Parameter angegeben haben).Pass that object parameter as a type-specific default value for your property (the default value provided must be the type you provided as the propertyType parameter in the Register call).

Für FrameworkPropertyMetadatakönnen Sie auch metadatenoptionsflags für Ihre Eigenschaft angeben.For FrameworkPropertyMetadata, you can also specify metadata option flags for your property. Diese Flags werden nach der Registrierung in diskrete Eigenschaften auf den Eigenschaftenmetadaten konvertiert und werden verwendet, um bestimmte Bedingungen an andere Prozesse zu kommunizieren, z.B. an die Layout-Engine.These flags are converted into discrete properties on the property metadata after registration and are used to communicate certain conditionals to other processes such as the layout engine.

Festlegen von Flags für die entsprechenden MetadatenSetting Appropriate Metadata Flags

  • Wenn sich Benutzeroberfläche (User Interface, UI)user interface (UI)die-Eigenschaft (oder Änderungen in ihrem Wert) auf auswirkt und sich insbesondere darauf auswirkt, wie das Layoutsystem das Element auf einer Seite anpassen oder darstellen soll, legen Sie mindestens eines der folgenden Flags AffectsRenderfest: AffectsMeasure, AffectsArrange,.If your property (or changes in its value) affects the Benutzeroberfläche (User Interface, UI)user interface (UI), and in particular affects how the layout system should size or render your element in a page, set one or more of the following flags: AffectsMeasure, AffectsArrange, AffectsRender.

    • AffectsMeasureGibt an, dass eine Änderung an dieser Eigenschaft eine Änderung UIUI am Rendering erfordert, bei der das enthaltende Objekt möglicherweise mehr oder weniger Platz innerhalb des übergeordneten Elements erfordert.AffectsMeasure indicates that a change to this property requires a change to UIUI rendering where the containing object might require more or less space within the parent. Für die Eigenschaft „Breite“ sollte beispielsweise dieses Flag festgelegt sein.For example, a "Width" property should have this flag set.

    • AffectsArrangeGibt an, dass eine Änderung an dieser Eigenschaft eine Änderung UIUI am Rendering erfordert, die in der Regel keine Änderung des dedizierten Speicherplatzes erfordert, sondern angibt, dass sich die Positionierung innerhalb des Speicherplatzes geändert hat.AffectsArrange indicates that a change to this property requires a change to UIUI rendering that typically does not require a change in the dedicated space, but does indicate that the positioning within the space has changed. Für die Eigenschaft „Ausrichtung“ sollte beispielsweise dieses Flag festgelegt sein.For example, an "Alignment" property should have this flag set.

    • AffectsRenderGibt an, dass eine andere Änderung aufgetreten ist, die sich nicht auf Layout und Measure auswirkt, aber ein anderes Rendering erfordert.AffectsRender indicates that some other change has occurred that will not affect layout and measure, but does require another render. Ein Beispiel wäre eine Eigenschaft, die eine Farbe eines vorhandenen Elements ändert, z.B. „Hintergrund“.An example would be a property that changes a color of an existing element, such as "Background".

    • Diese Flags werden in Metadaten häufig als ein Protokoll für Ihre eigenen Überschreibungsimplementierungen von Eigenschaftensystem oder Layoutrückrufen verwendet.These flags are often used as a protocol in metadata for your own override implementations of property system or layout callbacks. Beispielsweise könnten OnPropertyChanged Sie über einen Rückruf verfügen, der aufruft InvalidateArrange , wenn AffectsArrange eine Eigenschaft der-Instanz eine Änderung des Werts meldet und true wie in Ihren Metadaten.For instance, you might have an OnPropertyChanged callback that will call InvalidateArrange if any property of the instance reports a value change and has AffectsArrange as true in its metadata.

  • Manche Eigenschaften können Auswirkungen auf die Merkmale des Renderings des übergeordneten Elements haben, sowohl über und unter den Änderungen der oben genannten benötigten Größe.Some properties may affect the rendering characteristics of the containing parent element, in ways above and beyond the changes in required size mentioned above. Ein Beispiel hierfür ist MinOrphanLines die im Fluss Dokument Modell verwendete Eigenschaft, bei der Änderungen an dieser Eigenschaft das allgemeine Rendering des Fluss Dokuments ändern können, das den Absatz enthält.An example is the MinOrphanLines property used in the flow document model, where changes to that property can change the overall rendering of the flow document that contains the paragraph. Verwenden AffectsParentArrange Sie AffectsParentMeasure oder, um ähnliche Fälle in ihren eigenen Eigenschaften zu identifizieren.Use AffectsParentArrange or AffectsParentMeasure to identify similar cases in your own properties.

  • Standardmäßig unterstützen Abhängigkeitseigenschaften die Datenbindung.By default, dependency properties support data binding. Sie können die Datenbindung in Fällen bewusst deaktivieren, in denen kein realistisches Szenario für die Datenbindung besteht, oder in denen die Leistung der Datenbindung für ein großes Objekt als Problem erkannt wird.You can deliberately disable data binding, for cases where there is no realistic scenario for data binding, or where performance in data binding for a large object is recognized as a problem.

  • Standardmäßig ist die Daten Mode Bindung für Abhängigkeits Eigenschaften OneWaystandardmäßig auf.By default, data binding Mode for dependency properties defaults to OneWay. Sie können die Bindung jederzeit in TwoWay eine einzelne Bindungs Instanz ändern. Ausführliche Informationen finden Sie unter angeben der Bindungs Richtung.You can always change the binding to be TwoWay per binding instance; for details, see Specify the Direction of the Binding. Als Autor der Abhängigkeits Eigenschaft können Sie jedoch festlegen, dass die Eigenschaft den TwoWay Bindungs Modus standardmäßig verwendet.But as the dependency property author, you can choose to make the property use TwoWay binding mode by default. Ein Beispiel für eine vorhandene Abhängigkeits Eigenschaft MenuItem.IsSubmenuOpenist. das Szenario für diese Eigenschaft besteht darin IsSubmenuOpen , dass die Einstellungs Logik und die MenuItem Zusammensetzung von mit dem Standarddesign Stil interagieren.An example of an existing dependency property is MenuItem.IsSubmenuOpen; the scenario for this property is that the IsSubmenuOpen setting logic and the compositing of MenuItem interact with the default theme style. Die IsSubmenuOpen Eigenschafts Logik verwendet systemeigene Daten Bindungen, um den Status der Eigenschaft in Übereinstimmung mit anderen Zustands Eigenschaften und Methoden aufrufen beizubehalten.The IsSubmenuOpen property logic uses data binding natively to maintain the state of the property in accordance to other state properties and method calls. Eine andere Beispiel Eigenschaft, TwoWay die standardmäßig TextBox.Textgebunden wird, ist.Another example property that binds TwoWay by default is TextBox.Text.

  • Sie können die Eigenschaften Vererbung auch in einer benutzerdefinierten Abhängigkeits Eigenschaft Inherits aktivieren, indem Sie das-Flag festlegen.You can also enable property inheritance in a custom dependency property by setting the Inherits flag. Eigenschaftenvererbung eignet sich für ein Szenario, in dem übergeordnete und untergeordnete Elemente über eine gemeinsame Eigenschaft verfügen und es sinnvoll ist, dass das untergeordnete Element diesen bestimmten Eigenschaftswert auf den gleichen Wert wie das übergeordnete Element festlegt.Property inheritance is useful for a scenario where parent elements and child elements have a property in common, and it makes sense for the child elements to have that particular property value set to the same value as the parent set it. Ein Beispiel für eine Vererb DataContextBare Eigenschaft ist, die für Bindungs Vorgänge verwendet wird, um das wichtige Master/Detail-Szenario für die Datendarstellung zu aktivieren.An example inheritable property is DataContext, which is used for binding operations to enable the important master-detail scenario for data presentation. DataContext Durch Vererbung erbt jedes untergeordnete Element ebenfalls diesen Datenkontext.By making DataContext inheritable, any child elements inherit that data context also. Aufgrund der Vererbung von Eigenschaftswerten können Sie einen Datenkontext am Seiten- oder Anwendungsstamm angeben, und müssen ihn nicht für Bindungen in allen möglichen untergeordneten Elementen neu angeben.Because of property value inheritance, you can specify a data context at the page or application root, and do not need to respecify it for bindings in all possible child elements. DataContextist auch ein gutes Beispiel, um zu veranschaulichen, dass die Vererbung den Standardwert überschreibt, aber immer lokal auf ein bestimmtes untergeordnetes Element festgelegt werden kann. Weitere Informationen finden Sie unter Verwenden des Master/Detail-Musters mit hierarchischen Daten.DataContext is also a good example to illustrate that inheritance overrides the default value, but it can always be set locally on any particular child element; for details, see Use the Master-Detail Pattern with Hierarchical Data. Die Vererbung von Eigenschaftswerten kann zu Leistungseinbußen führen und sollte deswegen nur sparsam eingesetzt werden. Weitere Informationen hierzu finden Sie unter Vererbung von Eigenschaftswerten.Property value inheritance does have a possible performance cost, and thus should be used sparingly; for details, see Property Value Inheritance.

  • Legen Sie Journal das-Flag fest, um anzugeben, ob die Abhängigkeits Eigenschaft von Navigations Journal Diensten erkannt oder verwendet werden soll.Set the Journal flag to indicate if your dependency property should be detected or used by navigation journaling services. Ein Beispiel ist die SelectedIndex -Eigenschaft. jedes Element, das in einem Auswahl Steuerelement ausgewählt wurde, sollte beibehalten werden, wenn der Journal Verlauf navigiert wird.An example is the SelectedIndex property; any item selected in a selection control should be persisted when the journaling history is navigated.

Schreibgeschützte AbhängigkeitseigenschaftenRead-Only Dependency Properties

Sie können eine Abhängigkeitseigenschaft definieren, die schreibgeschützt ist.You can define a dependency property that is read-only. Allerdings unterscheiden sich die Szenarios, warum Sie eine Eigenschaft als schreibgeschützt definieren sollen. Dies ist auch beim Registrieren mit dem Eigenschaftensystem und Verfügbar machen des Bezeichners der Fall.However, the scenarios for why you might define your property as read-only are somewhat different, as is the procedure for registering them with the property system and exposing the identifier. Weitere Informationen finden Sie unter Schreibgeschützte Abhängigkeitseigenschaften.For more information, see Read-Only Dependency Properties.

Abhängigkeitseigenschaften vom AuflistungstypCollection-Type Dependency Properties

Bei Abhängigkeitseigenschaften vom Auflistungstyp gibt es zusätzliche Implementierungsprobleme, die man berücksichtigen sollte.Collection-type dependency properties have some additional implementation issues to consider. Weitere Informationen finden Sie unter Abhängigkeitseigenschaften vom Auflistungstyp.For details, see Collection-Type Dependency Properties.

Überlegungen zur Sicherheit von AbhängigkeitseigenschaftenDependency Property Security Considerations

Abhängigkeitseigenschaften sollten als öffentliche Eigenschaften deklariert werden.Dependency properties should be declared as public properties. Bezeichnerfelder für Abhängigkeitseigenschaften sollten als öffentliche statische Felder deklariert werden.Dependency property identifier fields should be declared as public static fields. Auch wenn Sie versuchen, andere Zugriffsebenen zu deklarieren (z. b. geschützt), kann auf eine Abhängigkeits Eigenschaft immer über den Bezeichner in Kombination mit den Eigenschaften System-APIs zugegriffen werden.Even if you attempt to declare other access levels (such as protected), a dependency property can always be accessed through the identifier in combination with the property system APIs. Der Zugriff auf ein geschütztes Bezeichnerfeld ist möglicherweise möglich, weil Metadatenberichte oder Wert Erstellungs-APIs, die Teil LocalValueEnumeratordes Eigenschaften Systems sind, wie z. b.Even a protected identifier field is potentially accessible because of metadata reporting or value determination APIs that are part of the property system, such as LocalValueEnumerator. Weitere Informationen finden Sie unter Sicherheit von Abhängigkeitseigenschaften.For more information, see Dependency Property Security.

Abhängigkeitseigenschaften und KlassenkonstruktorenDependency Properties and Class Constructors

Es ist ein allgemeines Prinzip für das Programmieren von verwaltetem Code (oft durch Codeanalysetools wie FxCop erzwungen), dass Klassenkonstruktoren keine virtuellen Methoden aufrufen dürfen.There is a general principle in managed code programming (often enforced by code analysis tools such as FxCop) that class constructors should not call virtual methods. Der Grund hierfür ist, dass Konstruktoren als Basisinitialisierung eines abgeleiteten Klassenkonstruktors aufgerufen werden können. Außerdem erfolgt der Eintritt in die virtuelle Methode über den Konstruktor möglicherweise bei einem unvollständigen Initialisierungszustand der erstellten Objektinstanz.This is because constructors can be called as base initialization of a derived class constructor, and entering the virtual method through the constructor might occur at an incomplete initialization state of the object instance being constructed. Wenn Sie von einer Klasse ableiten, die bereits von DependencyObjectabgeleitet ist, sollten Sie beachten, dass das Eigenschaften System selbst aufruft und virtuelle Methoden intern verfügbar macht.When you derive from any class that already derives from DependencyObject, you should be aware that the property system itself calls and exposes virtual methods internally. Diese virtuellen Methoden sind Teil der WPFWPF-Dienste für das Eigenschaftensystem.These virtual methods are part of the WPFWPF property system services. Das Überschreiben der Methoden ermöglicht abgeleiteten Klassen,beim Festlegen von Werten teilzunehmen.Overriding the methods enables derived classes to participate in value determination. Sie sollten die Werte der Abhängigkeitseigenschaft innerhalb von Klassenkonstruktoren nicht festlegen, solange Sie keinem sehr spezifischen Konstruktormuster folgen, um potentielle Probleme bei der Initialisierung der Runtime zu vermeiden.To avoid potential issues with runtime initialization, you should not set dependency property values within constructors of classes, unless you follow a very specific constructor pattern. Weitere Informationen finden Sie unter Sichere Konstruktormuster für DependencyObjects.For details, see Safe Constructor Patterns for DependencyObjects.

Siehe auchSee also