Benutzerdefinierte Abhängigkeitseigenschaften (WPF .NET)

Entwickler und Ersteller von WPF-Anwendungen (Windows Presentation Foundation) und -Komponenten können benutzerdefinierte Abhängigkeitseigenschaften erstellen, um die Funktionalität ihrer Eigenschaften zu erweitern. Im Gegensatz zu einer CLR-Eigenschaft (Common Language Runtime) fügt eine Abhängigkeitseigenschaft Unterstützung für Formatierung, Datenbindung, Vererbung, Animationen und Standardwerte hinzu. Background, Width und Text sind Beispiele für vorhandene Abhängigkeitseigenschaften in WPF-Klassen. In diesem Artikel wird beschrieben, wie Sie benutzerdefinierte Abhängigkeitseigenschaften implementieren und Optionen zur Verbesserung der Leistung, Benutzerfreundlichkeit und Vielseitigkeit darstellen.

Wichtig

Der Desktopleitfaden zu .NET 7 und .NET 6 ist in Bearbeitung.

Voraussetzungen

Im Artikel wird davon ausgegangen, dass sie grundlegende Kenntnisse über Abhängigkeitseigenschaften haben und eine Übersicht über Abhängigkeitseigenschaften gelesen haben. Um den Beispielen in diesem Artikel zu folgen, ist es hilfreich, wenn Sie mit Extensible Application Markup Language (XAML) vertraut sind und wissen, wie WPF-Anwendungen geschrieben werden.

Abhängigkeitseigenschaftsbezeichner

Abhängigkeitseigenschaften sind Eigenschaften, die beim WPF-Eigenschaftensystem über Register- oder RegisterReadOnly-Aufrufe registriert sind. Die Register-Methode gibt eine DependencyProperty-Instanz zurück, die den registrierten Namen und die Merkmale einer Abhängigkeitseigenschaft enthält. Sie weisen der DependencyProperty-Instanz ein statisches schreibgeschütztes Feld zu, das als Abhängigkeitseigenschaftsbezeichner bezeichnet wird, der gemäß Konvention den Namen <property name>Property trägt. Zum Beispiel lautet das Bezeichnerfeld für die Background-Eigenschaft immer BackgroundProperty.

Der Abhängigkeitseigenschaftsbezeichner wird als Unterstützungsfeld zum Abrufen oder Festlegen von Eigenschaftswerten verwendet, anstelle des Standardmusters zum Unterstützen einer Eigenschaft mit einem privaten Feld. Nicht nur verwendet das Eigenschaftensystem den Bezeichner, auch XAML-Prozessoren können ihn verwenden, und Ihr Code (sowie möglicherweise externer Code) kann auf Abhängigkeitseigenschaften über ihre Bezeichner zugreifen.

Abhängigkeitseigenschaften können nur auf von DependencyObject-Typen abgeleitete Klassen angewendet werden. Die meisten WPF-Klassen unterstützen Abhängigkeitseigenschaften, da DependencyObject sich in der Nähe des Stamms der WPF-Klassenhierarchie befindet. Weitere Informationen zu Abhängigkeitseigenschaften sowie zur Terminologie und den Konventionen für deren Beschreibung finden Sie unter Übersicht über Abhängigkeitseigenschaften.

Abhängigkeitseigenschaftenwrapper

WPF-Abhängigkeitseigenschaften, die keine angefügten Eigenschaften sind, werden von einem CLR-Wrapper verfügbar gemacht, der get- und set-Zugriffsmethoden implementiert. Mithilfe eines Eigenschaftenwrappers können Consumer von Abhängigkeitseigenschaften deren Werte so abrufen oder festlegen, wie bei jeder anderen CLR-Eigenschaft. Die Zugriffsmethoden get und set interagieren mit dem zugrunde liegenden Eigenschaftensystem durch DependencyObject.GetValue- und DependencyObject.SetValue-Aufrufe, wobei der Abhängigkeitseigenschaftsbezeichner als Parameter übergeben wird. Consumer von Abhängigkeitseigenschaften rufen GetValue oder SetValue in der Regel nicht direkt auf, aber wenn Sie eine benutzerdefinierte Abhängigkeitseigenschaft implementieren, verwenden Sie diese Methoden im Wrapper.

Wann eine Abhängigkeitseigenschaft implementiert wird

Wenn Sie eine Eigenschaft für eine Klasse implementieren, die von DependencyObject abgeleitet wird, machen Sie sie zu einer Abhängigkeitseigenschaft, indem Sie Ihre Eigenschaft mit einem DependencyProperty-Bezeichner unterstützen. Ob es nützlich ist, eine Abhängigkeitseigenschaft zu erstellen, hängt von Ihrem Szenario ab. Die Unterstützung Ihrer Eigenschaft mit einem privaten Feld ist für einige Szenarien zwar geeignet, Sie sollten aber über die Implementierung einer Abhängigkeitseigenschaft nachdenken, wenn Ihre Eigenschaft eine oder mehrere der folgenden WPF-Funktionen unterstützen soll:

  • Eigenschaften, die innerhalb eines Stils festgelegt werden können. Weitere Informationen finden Sie unter Stile und Vorlagen.

  • Eigenschaften, die Datenbindung unterstützen. Weitere Informationen zur Datenbindung mit Abhängigkeitseigenschaften finden Sie unter Binden der Eigenschaften von zwei Steuerelementen.

  • Eigenschaften, die über dynamische Ressourcenverweise festgelegt werden können. Weitere Informationen finden Sie unter XAML-Ressourcen.

  • Eigenschaften, die ihren Wert automatisch von einem übergeordneten Element in der Elementstruktur erben. Dazu müssen Sie die Verwendung mit RegisterAttached registrieren, auch wenn Sie einen Eigenschaftenwrapper für CLR-Zugriff erstellen. Weitere Informationen finden Sie unter Vererbung von Eigenschaftswerten.

  • Eigenschaften, die animierbar sind. Weitere Informationen finden Sie unter Übersicht über Animation.

  • Benachrichtigung durch das WPF-Eigenschaftensystem, wenn sich ein Eigenschaftswert ändert. Änderungen können aufgrund von Aktionen des Eigenschaftensystems, der Umgebung, des Benutzers oder des Stils erforderlich werden. Ihre Eigenschaft kann eine Rückrufmethode in Eigenschaftenmetadaten angeben, die jedes Mal aufgerufen wird, wenn das Eigenschaftensystem feststellt, dass der Eigenschaftswert geändert wurde. Ein verwandtes Konzept ist die Koersion des Eigenschaftswerts. Weitere Informationen finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften.

  • Zugriff auf Metadaten für Abhängigkeitseigenschaften, die von WPF-Prozessen gelesen werden. Sie können Eigenschaftenmetadaten beispielsweise für folgende Zwecke verwenden:

    • Geben Sie an, ob das Layoutsystem aufgrund eines geänderten Abhängigkeitseigenschaftswerts die visuellen Objekte für ein Element neu aufbauen soll.

    • Legen Sie den Standardwert einer Abhängigkeitseigenschaft fest, indem Sie Metadaten für abgeleitete Klassen überschreiben.

  • Visual Studio WPF-Designerunterstützung, z. B. die Bearbeitung der Eigenschaften eines benutzerdefinierten Steuerelements im Eigenschaftenfenster. Weitere Informationen finden Sie unter Übersicht über das Erstellen von Steuerelementen.

Für einige Szenarien ist das Überschreiben der Metadaten einer vorhandenen Abhängigkeitseigenschaft eine bessere Option als die Implementierung einer neuen Abhängigkeitseigenschaft. Ob die Überschreibung von Metadaten sinnvoll ist hängt von Ihrem Szenario ab und wie sehr dieses Szenario der Implementierung vorhandener WPF-Abhängigkeitseigenschaften und -Klassen ähnelt. Weitere Informationen zum Überschreiben der Metadaten von vorhandenen Abhängigkeitseigenschaften finden Sie unter Metadaten für Abhängigkeitseigenschaften.

Prüfliste für die Erstellung einer Abhängigkeitseigenschaft

Führen Sie die folgenden Schritte aus, um eine Abhängigkeitseigenschaft zu erstellen. Einige der Schritte können in einer einzelnen Codezeile kombiniert und implementiert werden.

  1. (Optional) Erstellen Sie Metadaten für Abhängigkeitseigenschaften.

  2. Registrieren Sie die Abhängigkeitseigenschaft beim Eigenschaftensystem, legen Sie einen Eigenschaftsnamen, einen Besitzertyp, den Typ des Eigenschaftswerts und optional Eigenschaftenmetadaten an.

  3. Definieren Sie einen DependencyProperty-Bezeichner als ein public static readonly-Feld des Besitzertyps. Der Name des Bezeichnerfelds ist der Eigenschaftsname mit angefügten Property-Suffixen.

  4. Definieren Sie eine CLR-Wrappereigenschaft, die denselben Namen wie die Abhängigkeitseigenschaft trägt. Implementieren Sie im CLR-Wrapper die Zugriffsmethoden get und set, die eine Verbindung mit der den Wrapper unterstützenden Abhängigkeitseigenschaft herstellen.

Registrieren der Eigenschaft

Damit Ihre Eigenschaft eine Abhängigkeitseigenschaft ist, müssen Sie sie beim Eigenschaftensystem registrieren. Um Ihre Eigenschaft zu registrieren, rufen Sie die Register-Methode aus dem Textkörper Ihrer Klasse heraus auf, aber außerhalb aller Memberdefinitionen. Die Methode Register gibt einen eindeutigen Abhängigkeitseigenschaftsbezeichner zurück, den Sie beim Aufrufen der Eigenschaftensystem-API verwenden. Der Grund dafür, dass der Register-Aufruf außerhalb von Memberdefinitionen vorgenommen werden muss, besteht darin, dass Sie den Rückgabewert einem public static readonly-Feld des Typs DependencyPropertyzuweisen. Dieses Feld, das Sie in Ihrer Klasse erstellen, ist der Bezeichner für Ihre Abhängigkeitseigenschaft. Im folgenden Beispiel benennt das erste Argument von Register die Abhängigkeitseigenschaft AquariumGraphic.

// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumGraphicProperty =
    DependencyProperty.Register(
      name: "AquariumGraphic",
      propertyType: typeof(Uri),
      ownerType: typeof(Aquarium),
      typeMetadata: new FrameworkPropertyMetadata(
          defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
          flags: FrameworkPropertyMetadataOptions.AffectsRender,
          propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
    );
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
    DependencyProperty.Register(
        name:="AquariumGraphic",
        propertyType:=GetType(Uri),
        ownerType:=GetType(Aquarium),
        typeMetadata:=New FrameworkPropertyMetadata(
            defaultValue:=New Uri("http://www.contoso.com/aquarium-graphic.jpg"),
            flags:=FrameworkPropertyMetadataOptions.AffectsRender,
            propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))

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. Diese Vorgehensweise kann sinnvoll sein, wenn Sie mehr als eine Codezeile benötigen, um die Abhängigkeitseigenschaft zu initialisieren.

Benennen der Abhängigkeitseigenschaft

Die etablierte Benennungskonvention für Abhängigkeitseigenschaften ist obligatorisch für normales Verhalten des Eigenschaftensystems. Der Name des von Ihnen erstellten Bezeichnerfelds muss der registrierte Name der Eigenschaft mit dem Suffix Property sein.

Ein Abhängigkeitseigenschaftsname muss innerhalb der Registrierungsklasse eindeutig sein. Abhängigkeitseigenschaften, die über einen Basistyp geerbt werden, wurden bereits registriert und können nicht von einem abgeleiteten Typ registriert werden. Sie können jedoch eine Abhängigkeitseigenschaft verwenden, die von einem anderen Typ registriert wurde, selbst wenn es sich um einen Typ handelt, von dem Ihre Klasse nicht erbt, indem Sie Ihre Klasse als Besitzer der Abhängigkeitseigenschaft hinzufügen. Weitere Informationen zum Hinzufügen einer Klasse als Besitzer finden Sie unter Metadaten für Abhängigkeitseigenschaften.

Implementieren eines Eigenschaftenwrappers

Standardmäßig muss der Name der Wrappereigenschaft mit dem ersten Parameter des Register-Aufrufs identisch sein, bei dem es sich um den Namen der Abhängigkeitseigenschaft handelt. Ihre Wrapperimplementierung ruft GetValue in der get-Zugriffsmethoden und SetValue in der set-Zugriffsmethode (für Lese-/Schreibeigenschaften) auf. Im folgenden Beispiel wird ein Wrapper dargestellt – nach Registrierungsaufruf und Bezeichnerfelddeklaration. Alle öffentlichen Abhängigkeitseigenschaften für WPF-Klassen verwenden ein ähnliches Wrappermodell.

// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumGraphicProperty =
    DependencyProperty.Register(
      name: "AquariumGraphic",
      propertyType: typeof(Uri),
      ownerType: typeof(Aquarium),
      typeMetadata: new FrameworkPropertyMetadata(
          defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
          flags: FrameworkPropertyMetadataOptions.AffectsRender,
          propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
    );

// Declare a read-write property wrapper.
public Uri AquariumGraphic
{
    get => (Uri)GetValue(AquariumGraphicProperty);
    set => SetValue(AquariumGraphicProperty, value);
}
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
    DependencyProperty.Register(
        name:="AquariumGraphic",
        propertyType:=GetType(Uri),
        ownerType:=GetType(Aquarium),
        typeMetadata:=New FrameworkPropertyMetadata(
            defaultValue:=New Uri("http://www.contoso.com/aquarium-graphic.jpg"),
            flags:=FrameworkPropertyMetadataOptions.AffectsRender,
            propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))

' Declare a read-write property wrapper.
Public Property AquariumGraphic As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set
        SetValue(AquariumGraphicProperty, Value)
    End Set
End Property

Außer in seltenen Ausnahmefällen sollte ihre Wrapperimplementierung nur GetValue- und SetValue-Code enthalten. Die Gründe finden Sie unter Auswirkungen für benutzerdefinierte Abhängigkeitseigenschaften.

Wenn Ihre Eigenschaft keiner etablierten Benennungskonventionen folgt, entstehen möglicherweise folgende Probleme:

  • Einige Aspekte von Stilen und Vorlagen funktionieren nicht.

  • Die meisten Tools und Designer verlassen sich auf Benennungskonventionen, um XAML ordnungsgemäß zu serialisieren und um Unterstützung für eine Entwicklerumgebung auf Ebene einzelner Eigenschaften zu bieten.

  • Die aktuelle Implementierung des WPF XAML-Ladeprogramms umgeht die Wrapper komplett und verlässt sich beim Verarbeiten von Attributwerten auf die Benennungskonvention. Weitere Informationen finden Sie unter Laden von XAML und Abhängigkeitseigenschaften.

Metadaten für Abhängigkeitseigenschaften

Wenn Sie eine Abhängigkeitseigenschaft registrieren, erstellt das Eigenschaftensystem ein Metadatenobjekt, das Merkmale der Eigenschaft speichert. Overloads der Register-Methode ermöglichen es Ihnen, Eigenschaftenmetadaten während der Registrierung anzugeben, z. B. Register(String, Type, Type, PropertyMetadata). Eine allgemeine Verwendung von Eigenschaftenmetadaten besteht darin, einen benutzerdefinierten Standardwert für neue Instanzen anzuwenden, die eine Abhängigkeitseigenschaft verwenden. Wenn Sie keine Eigenschaftenmetadaten bereitstellen, weist das Eigenschaftensystem vielen der Merkmale von Abhängigkeitseigenschaften Standardwerte zu.

Wenn Sie eine Abhängigkeitseigenschaft für eine von einem FrameworkElement-Objekt abgeleiteten Klasse erstellen, können Sie die spezialisiertere Metadatenklasse FrameworkPropertyMetadata anstelle der Basisklasse PropertyMetadataverwenden. Mit mehreren FrameworkPropertyMetadata-Konstruktorsignaturen können Sie verschiedene Kombinationen von Metadateneigenschaften festlegen. Wenn Sie nur einen Standardwert angeben möchten, verwenden FrameworkPropertyMetadata(Object), und übergeben Sie den Standardwert an den Parameter Object. Stellen Sie sicher, dass der Werttyp dem im Register-Aufruf angegebenen propertyType entspricht.

Bei einigen FrameworkPropertyMetadata-Overloads können Sie Metadatenoptionsflags für Ihre Eigenschaft angeben. Das Eigenschaftensystem wandelt diese Flags in einzelne Eigenschaften um, und die Flagwerte werden von WPF-Prozessen wie dem Layoutmodul verwendet.

Festlegen von Metadatenflags

Berücksichtigen Sie beim Festlegen von Metadatenflags Folgendes:

  • Wenn sich ihr Eigenschaftswert (oder Änderungen daran) darauf auswirkt, wie das Layoutsystem ein Benutzeroberflächenelement rendert, legen Sie ein oder mehrere der folgenden Flags fest:

    • AffectsMeasure gibt an, dass eine Änderung des Eigenschaftswerts eine Änderung des UI-Rendering erfordert, insbesondere des von einem Objekt innerhalb des übergeordneten Elements belegte Speicherplatzes. Legen Sie dieses Metadatenflag z. B. für eine Width-Eigenschaft fest.

    • AffectsArrange gibt an, dass eine Änderung des Eigenschaftswerts eine Änderung des UI-Rendering erfordert, insbesondere der Position eines Objekts innerhalb des übergeordneten Elements. In der Regel ändert sich die Größe des Objekts nicht. Legen Sie dieses Metadatenflag z. B. für eine Alignment-Eigenschaft fest.

    • AffectsRender gibt an, dass eine Änderung erfolgt ist, die Layout und Maß nicht beeinflusst, aber dennoch ein weiteres Rendern erfordert. Legen Sie dieses Flag beispielsweise für eine Background-Eigenschaft oder eine andere Eigenschaft fest, die sich auf die Farbe eines Elements auswirkt.

    Sie können diese Flags auch als Eingaben für Ihre Überschreibungsimplementierungen für die Rückrufe des Eigenschaftssystems (oder Layouts) verwenden. Sie können zum Beispiel einen OnPropertyChanged-Rückruf verwenden, der InvalidateArrange aufruft, wenn eine Eigenschaft der Instanz eine Wertänderung meldet und AffectsArrange in den Metadaten festgelegt wurde.

  • Einige Eigenschaften wirken sich auf andere Weise auf die Renderingeigenschaften ihres übergeordneten Elements aus. Beispielsweise können Änderungen an der MinOrphanLines-Eigenschaft das Gesamtrendering eines Flussdokuments ändern. Verwenden Sie AffectsParentArrange oder AffectsParentMeasure, um übergeordnete Aktionen in Ihren eigenen Eigenschaften zu signalisieren.

  • Standardmäßig unterstützen Abhängigkeitseigenschaften die Datenbindung. Sie können jedoch IsDataBindingAllowed verwenden, um die Datenbindung zu deaktivieren, wenn es kein realistisches Szenario dafür gibt, oder wenn die Datenbindungsleistung problematisch ist, z. B. bei großen Objekten.

  • Obwohl der Standarddatenbindungs-Modus für Abhängigkeitseigenschaften OneWay ist, können Sie den Bindungsmodus einer bestimmten Bindung in TwoWay ändern. Weitere Informationen finden Sie unter Bindungsrichtung. Als Autor von Abhängigkeitseigenschaften können Sie die bidirektionale Bindung sogar zum Standardmodus machen. Ein Beispiel für eine vorhandene Abhängigkeitseigenschaft, die eine bidirektionale Datenbindung verwendet, ist MenuItem.IsSubmenuOpen, dessen einen Zustand auf anderen Eigenschaften und Methodenaufrufen basiert. Das Szenario für IsSubmenuOpen besteht darin, dass seine Einstellungslogik und das Zusammensetzen von MenuItem mit dem Standarddesignstil interagieren. TextBox.Text ist eine weitere WPF-Abhängigkeitseigenschaft, die standardmäßig eine bidirektionale Bindung verwendet.

  • Sie können die Eigenschaftenvererbung für Ihre Abhängigkeitseigenschaft aktivieren, indem Sie das Flag Inherits festlegen. Die Eigenschaftsvererbung ist nützlich für Szenarien, in denen übergeordnete und untergeordnete Elemente über eine gemeinsame Eigenschaft verfügen, und es sinnvoll ist, dass das untergeordnete Element den Wert des übergeordneten Elements für die gemeinsame Eigenschaft erbt. Ein Beispiel für eine vererbbare Eigenschaft ist DataContext, die Bindungsvorgänge unterstützt, die das Master-Detail-Szenario für die Datenpräsentation verwenden. Mit der Vererbung von Eigenschaftswerten können Sie einen Datenkontext auf der Seite oder dem Anwendungsstamm angeben, wodurch dieser für untergeordnete Elementbindungen nicht mehr angegeben werden muss. Ein geerbter Eigenschaftswert überschreibt den Standardwert zwar, Eigenschaftswerte können aber lokal für jedes untergeordnete Element festgelegt werden. Verwenden Sie die Vererbung von Eigenschaftswerten sparsam, da sie Leistungskosten verursacht. Weitere Informationen finden Sie unter Vererbung von Eigenschaftswerten.

  • Legen Sie das Flag Journal so fest, dass es angibt, dass Ihre Abhängigkeitseigenschaft ermittelt werden oder von Navigationsjournalingdiensten verwendet werden soll. Die Eigenschaft SelectedIndex legt z. B. das Journal-Flag fest, um zu empfehlen, dass Anwendungen einen Journalverlauf der ausgewählten Elemente beibehalten.

Schreibgeschützte Abhängigkeitseigenschaften

Sie können eine Abhängigkeitseigenschaft definieren, die schreibgeschützt ist. Ein typisches Szenario ist eine Abhängigkeitseigenschaft, die den internen Zustand speichert. IsMouseOver ist beispielsweise schreibgeschützt, da sein Zustand nur durch Mauseingaben bestimmt werden sollte. Weitere Informationen finden Sie unter Schreibgeschützte Abhängigkeitseigenschaften.

Abhängigkeitseigenschaften des Sammlungstyps

Bei Abhängigkeitseigenschaften vom Typ „Sammlung“ sind zusätzliche Dinge bei der Implementierung zu berücksichtigen, z. B. das Festlegen eines Standardwerts für Verweistypen und Datenbindungsunterstützung für Sammlungselemente. Weitere Informationen finden Sie unter Abhängigkeitseigenschaften vom Typ „Sammlung“.

Sicherheit von Abhängigkeitseigenschaften

In der Regel deklarieren Sie Abhängigkeitseigenschaften als öffentliche Eigenschaften und DependencyProperty-Bezeichnerfelder als public static readonly-Felder. Wenn Sie eine restriktivere Zugriffsstufe angeben, z. B. protected, kann auf eine Abhängigkeitseigenschaft weiterhin über ihren Bezeichner in Kombination mit Eigenschaftensystem-APIs zugegriffen werden. Selbst auf ein geschütztes Bezeichnerfeld kann potenziell über WPF-Metadatenberichte oder Wertermittlungs-APIs wie LocalValueEnumerator zugegriffen werden. Weitere Informationen finden Sie unter Sicherheit von Abhängigkeitseigenschaften.

Bei schreibgeschützten Abhängigkeitseigenschaften wird von RegisterReadOnly der Wert DependencyPropertyKey zurückgegeben, und normalerweise machen Sie DependencyPropertyKey nicht zu einem public-Member Ihrer Klasse. Da das WPF-Eigenschaftensystem den DependencyPropertyKey nicht außerhalb des externen Codes verteilt, weist eine schreibgeschützte Abhängigkeitseigenschaft eine bessere set-Sicherheit auf als eine Abhängigkeitseigenschaft mit Lese-/Schreibzugriff.

Abhängigkeitseigenschaften und Klassenkonstruktoren

Es ist ein allgemeines Prinzip für das Programmieren von verwaltetem Code (oft durch Codeanalysetools erzwungen), dass Klassenkonstruktoren keine virtuellen Methoden aufrufen dürfen. Dies liegt daran, dass Basiskonstruktoren während der Initialisierung eines abgeleiteten Klassenkonstruktors aufgerufen werden können, und eine virtuelle Methode, die von einem Basiskonstruktor aufgerufen wird, vor Abschluss der Initialisierung der abgeleiteten Klasse ausgeführt werden kann. Beim Ableiten von einer bereits von DependencyObject abgeleiteten Klasse gilt, dass das Eigenschaftensystem selbst virtuelle Methoden intern aufruft und verfügbar macht. Diese virtuellen Methoden sind Teil der WPF-Eigenschaftensystemdienste. Das Überschreiben der Methoden ermöglicht abgeleiteten Klassen,beim Festlegen von Werten teilzunehmen. Sie sollten die Werte der Abhängigkeitseigenschaft innerhalb von Klassenkonstruktoren nicht festlegen, solange Sie keinem spezifischen Konstruktormuster folgen, um potentielle Probleme bei der Initialisierung der Runtime zu vermeiden. Weitere Informationen finden Sie unter Sichere Konstruktormuster für DependencyObjects.

Weitere Informationen