Freigeben über


Benutzerdefinierte Abhängigkeitseigenschaften (WPF .NET)

Entwickler und Komponentenautoren von Windows Presentation Foundation (WPF) können benutzerdefinierte Abhängigkeitseigenschaften erstellen, um die Funktionalität ihrer Eigenschaften zu erweitern. Im Gegensatz zu einer Common Language Runtime (CLR) -Eigenschaftbietet eine Abhängigkeitseigenschaft Unterstützung für Styling, Datenbindung, Vererbung, Animationen und Standardwerte. Background, Widthund 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.

Voraussetzungen

In dem Artikel wird ein grundlegendes Wissen über Abhängigkeitseigenschaften vorausgesetzt, sowie dass Sie die Übersicht zu Abhängigkeitseigenschaftengelesen haben. Um den Beispielen in diesem Artikel zu folgen, hilft es Ihnen, wenn Sie mit Extensible Application Markup Language (XAML) vertraut sind und wissen, wie WPF-Anwendungen geschrieben werden.

Bezeichner der Abhängigkeitseigenschaft

Abhängigkeitseigenschaften sind Eigenschaften, die über Register- oder RegisterReadOnly-Aufrufe beim WPF-Eigenschaftensystem registriert werden. Die Register-Methode gibt eine DependencyProperty-Instanz zurück, die den registrierten Namen und die Merkmale einer Abhängigkeitseigenschaft enthält. Sie weisen die DependencyProperty Instanz einem statischen Readonly-Feld zu, das als Abhängigkeitseigenschaftsbezeichner bezeichnet wird,, dass nach Konvention <property name>Propertybenannt wird. Beispielsweise ist das Bezeichnerfeld für die Eigenschaft Background immer BackgroundProperty.

Der Bezeichner der Abhängigkeitseigenschaft wird als Hintergrundfeld zum Abrufen oder Festlegen von Eigenschaftswerten verwendet, anstelle des Standardmusters, eine Eigenschaft mit einem privaten Feld zu hinterlegen. Das Eigenschaftensystem verwendet nicht nur den Bezeichner, XAML-Prozessoren können ihn verwenden, und Ihr Code (und möglicherweise externer Code) kann über ihre Bezeichner auf Abhängigkeitseigenschaften zugreifen.

Abhängigkeitseigenschaften können nur auf Klassen angewendet werden, die von DependencyObject Typen abgeleitet werden. Die meisten WPF-Klassen unterstützen Abhängigkeitseigenschaften, da DependencyObject nahe am Stamm der WPF-Klassenhierarchie liegt. Weitere Informationen zu Abhängigkeitseigenschaften und der Terminologie und Konventionen, die zum Beschreiben verwendet werden, finden Sie unter Übersicht über Abhängigkeitseigenschaften.

Wrapper für Abhängigkeitseigenschaften

WPF-Abhängigkeitseigenschaften, die keine angefügten Eigenschaften sind, werden von einem CLR-Wrapper verfügbar gemacht, der get und set Accessoren implementiert. Mithilfe eines Eigenschaftenwrappers können Benutzer von Abhängigkeitseigenschaften Abhängigkeitseigenschaften abrufen oder festlegen, genauso wie jede andere CLR-Eigenschaft. Die Zugriffsfunktionen get und set interagieren mit dem zugrunde liegenden Eigenschaftensystem durch DependencyObject.GetValue- und DependencyObject.SetValue-Aufrufe, wobei der Bezeichner der Eigenschaft der Abhängigkeiten als Parameter übergeben wird. Benutzer von Abhängigkeitseigenschaften rufen normalerweise GetValue oder SetValue nicht direkt auf, aber wenn Sie eine benutzerdefinierte Abhängigkeitseigenschaft implementieren, verwenden Sie diese Methoden im Wrapper.

Wann eine Abhängigkeitseigenschaft implementiert werden soll

Wenn Sie eine Eigenschaft für eine Klasse implementieren, die von DependencyObjectabgeleitet wird, machen Sie sie zu einer Abhängigkeitseigenschaft, indem Sie Ihre Eigenschaft mit einem DependencyProperty Bezeichner unterstützen. Ob es vorteilhaft ist, eine Abhängigkeitseigenschaft zu erstellen, hängt von Ihrem Szenario ab. Obwohl die Sicherung Ihrer Eigenschaft mit einem privaten Feld für einige Szenarien ausreichend ist, sollten Sie eine Abhängigkeitseigenschaft implementieren, 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 Designvorlagen.

  • Eigenschaften, die die Datenbindung unterstützen. Weitere Informationen über die Abhängigkeitseigenschaften bei der Datenbindung 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 sich mit RegisterAttachedregistrieren, auch wenn Sie auch einen Eigenschaftenwrapper für den CLR-Zugriff erstellen. Weitere Informationen finden Sie unter Eigenschaftswertvererbung.

  • Eigenschaften, die animierbar sind. Weitere Informationen finden Sie in der Animationsübersicht.

  • Benachrichtigung durch das WPF-Eigenschaftensystem, wenn sich ein Eigenschaftswert ändert. Änderungen können auf Aktionen durch das Eigenschaftensystem, die Umgebung, den Benutzer oder die Formatvorlagen zurückzuführen sein. Ihre Eigenschaft kann eine Rückrufmethode in Eigenschaftsmetadaten angeben, die jedes Mal aufgerufen wird, wenn das Eigenschaftensystem bestimmt, dass der Eigenschaftswert geändert wurde. Ein verwandtes Konzept ist die Koersion des Eigenschaftswerts. Weitere Informationen finden Sie unter Dependency Property Rückrufe und Validierung.

  • Zugriff auf Metadaten von Abhängigkeitseigenschaften, die von WPF-Prozessen gelesen werden. Sie können beispielsweise Eigenschaftsmetadaten verwenden, um:

    • Geben Sie an, ob ein geänderter Abhängigkeitseigenschaftswert das Layoutsystem die visuellen Elemente für ein Element neu anordnen soll.

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

  • Visual Studio WPF-Designer Unterstützung, wie das Bearbeiten der Eigenschaften eines benutzerdefinierten Steuerelements im Eigenschaften Fenster. Weitere Informationen finden Sie unter Übersicht über die Steuerelementerstellung.

Für einige Szenarien ist das Überschreiben der Metadaten einer vorhandenen Abhängigkeitseigenschaft eine bessere Option als die Implementierung einer neuen Abhängigkeitseigenschaft. Ob eine Außerkraftsetzung von Metadaten praktisch ist, hängt von Ihrem Szenario ab und wie genau das Szenario der Implementierung vorhandener WPF-Abhängigkeitseigenschaften und -klassen ähnelt. Weitere Informationen zum Überschreiben von Metadaten für bestehende Abhängigkeitseigenschaften finden Sie unter Metadaten der Abhängigkeitseigenschaft.

Prüfliste zum Erstellen einer Abhängigkeitseigenschaft

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

  1. Erstellen Sie optional Metadaten für Abhängigkeitseigenschaften.

  2. Registrieren Sie die Abhängigkeitseigenschaft beim Eigenschaftensystem, geben Sie einen Eigenschaftsnamen, einen Besitzertyp, den Eigenschaftswerttyp und optional Eigenschaftenmetadaten an.

  3. Definieren Sie den Bezeichner DependencyProperty als das Feld public static readonly beim Besitzertyp. Der Name des Bezeichnerfelds ist der Eigenschaftenname, versehen mit dem Suffix Property.

  4. Definieren Sie eine CLR-Wrappereigenschaft mit demselben Namen wie der Name der Abhängigkeitseigenschaft. Implementieren Sie im CLR-Wrapper get- und set-Accessoren, die eine Verbindung mit der Abhängigkeitseigenschaft herstellen, die dem Wrapper zugrunde liegt.

Registrierung des Grundstücks

Damit Ihre Eigenschaft eine Abhängigkeitseigenschaft sein kann, müssen Sie sie beim Eigenschaftensystem registrieren. Rufen Sie zum Registrieren Ihrer Property die Register-Methode im Rumpf Ihrer Klasse, jedoch außerhalb von Memberdefinitionen, auf. Die Register-Methode gibt einen eindeutigen Bezeichner der Abhängigkeitseigenschaft zurück, den Sie beim Aufrufen der Eigenschaftensystem-API verwenden. Der Grund dafür, dass der Aufruf Register außerhalb von Mitgliedsdefinitionen erfolgt, 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)))

Anmerkung

Das Definieren der Abhängigkeitseigenschaft im Klassentext ist die typische Implementierung, aber es ist auch möglich, eine Abhängigkeitseigenschaft im statischen Klassenkonstruktor zu definieren. Dieser Ansatz kann sinnvoll sein, wenn Sie mehr als eine Codezeile zum Initialisieren der Abhängigkeitseigenschaft benötigen.

Benennung von Abhängigkeitseigenschaften

Die festgelegte Benennungskonvention für Abhängigkeitseigenschaften ist für das normale Verhalten des Eigenschaftensystems obligatorisch. Der Name des bezeichnerfelds, das Sie erstellen, muss der registrierte Name der Eigenschaft mit dem Suffix Propertysein.

Ein Abhängigkeitseigenschaftsname muss innerhalb der registrierenden Klasse 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 von einem Typ, 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 Eigentümer finden Sie unter Metadaten der Abhängigkeitseigenschaft.

Implementieren eines Eigenschaftenwrappers

Standardmäßig muss der Name der Wrappereigenschaft mit dem ersten Parameter des aufrufs Register identisch sein, bei dem es sich um den Namen der Abhängigkeitseigenschaft handelt. Ihre Wrapperimplementierung ruft GetValue im get Accessor auf und SetValue im set Accessor (für Lese-/Schreibeigenschaften). Das folgende Beispiel zeigt einen Wrapper nach der Deklaration des Registrierungsaufrufs und des Bezeichnerfelds. 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 Fällen sollte die Wrapper-Implementierung nur den GetValue und SetValue Code enthalten. Die Gründe dafür finden Sie unter Auswirkungen für benutzerdefinierte Abhängigkeitseigenschaften.

Wenn Ihre Immobilie nicht den etablierten Benennungskonventionen folgt, können möglicherweise die folgenden Probleme auftreten:

  • Einige Aspekte von Stilen und Vorlagen funktionieren nicht.

  • Die meisten Tools und Designer verwenden die Namenskonventionen, um XAML korrekt zu serialisieren und Unterstützung innerhalb der Designerumgebung auf Eigenschaftsebene bereitzustellen.

  • Die aktuelle Implementierung des WPF-XAML-Ladeprogramms umgeht die Wrapper vollständig und beruht auf der Namenskonvention zur Verarbeitung von Attributwerten. Weitere Informationen finden Sie unter XAML-Lade- und Abhängigkeitseigenschaften.

Metadaten der Abhängigkeitseigenschaft

Wenn Sie eine Abhängigkeitseigenschaft registrieren, erstellt das Eigenschaftensystem ein Metadatenobjekt zum Speichern von Eigenschaftenmerkmalen. Überladungen der Register-Methode ermöglichen Ihnen, während der Registrierung Eigenschaftsmetadaten anzugeben, z. B. Register(String, Type, Type, PropertyMetadata). Eine häufige Verwendung von Eigenschaftsmetadaten 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 Abhängigkeitseigenschaften Standardwerte zu.

Wenn Sie eine Abhängigkeitseigenschaft für eine von FrameworkElementabgeleitete Klasse erstellen, können Sie die speziellere Metadatenklasse FrameworkPropertyMetadata anstelle ihrer Basisklasse PropertyMetadataverwenden. Mit mehreren FrameworkPropertyMetadata Konstruktorsignaturen können Sie verschiedene Kombinationen von Metadatenmerkmalen angeben. Wenn Sie nur einen Standardwert angeben möchten, verwenden Sie FrameworkPropertyMetadata(Object), und übergeben Sie den Standardwert an den parameter Object. Stellen Sie sicher, dass der Werttyp dem propertyType entspricht, das im Register-Aufruf angegeben ist.

Bei einigen FrameworkPropertyMetadata Überladungen können Sie Metadaten-Optionskennzeichen für Ihre Eigenschaft angeben. Das Eigenschaftensystem konvertiert diese Flags in diskrete Eigenschaften, und die Flagwerte werden von WPF-Prozessen verwendet, wie z. B. der Layout-Engine.

Festlegen von Metadatenkennzeichnungen

Beachten Sie beim Festlegen von Metadatenkennzeichnungen Folgendes:

  • Wenn sich der Eigenschaftswert (oder die Änderungen daran) darauf auswirken, wie das Layoutsystem ein UI-Element darstellt, sollten Sie eines oder mehrere der folgenden Flags festlegen:

    • AffectsMeasure, das angibt, dass eine Änderung des Eigenschaftswerts eine Änderung des UI-Renderings erfordert, insbesondere des Raums, den ein Objekt innerhalb seines übergeordneten Elements einnimmt. Legen Sie z. B. dieses Metadaten-Flag für eine Width-Eigenschaft fest.

    • AffectsArrange, das darauf hinweist, dass eine Eigenschaftswertänderung eine Änderung der UI-Darstellung erfordert, insbesondere der Position eines Objekts innerhalb des übergeordneten Objekts. In der Regel ändert sich die Größe des Objekts nicht. Legen Sie beispielsweise dieses Metadaten-Flag für eine Alignment-Eigenschaft fest.

    • AffectsRender, was angibt, dass eine Änderung aufgetreten ist, die sich nicht auf das Layout und die Messung auswirkt, aber dennoch ein anderes Rendern erfordert. Legen Sie z. B. dieses Kennzeichen 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 Eingabewerte für Ihre Implementierungen zur Außerkraftsetzung der Rückruffunktionen des Eigenschaftssystems (oder Layouts) verwenden. Sie können beispielsweise ein OnPropertyChanged-Callback verwenden, um InvalidateArrange aufzurufen, wenn eine Eigenschaft der Instanz eine Wertänderung meldet und AffectsArrange im Metadatenbereich festgelegt ist.

  • Einige Eigenschaften beeinflussen die Darstellungseigenschaften des übergeordneten Elements auf unterschiedliche Weise. Beispielsweise können Änderungen an der MinOrphanLines-Eigenschaft die Gesamtdarstellung eines Flussdokuments ändern. Verwenden Sie AffectsParentArrange oder AffectsParentMeasure, um übergeordnete Aktionen in Ihren eigenen Eigenschaften zu signalisieren.

  • Abhängigkeitseigenschaften unterstützen standardmäßig die Datenbindung. Sie können jedoch IsDataBindingAllowed verwenden, um die Datenbindung zu deaktivieren, wenn es kein realistisches Szenario dafür gibt oder wenn die Leistung der Datenbindung problematisch ist, z. B. für große Objekte.

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

  • Sie können die Eigenschaftsvererbung für Ihre Abhängigkeitseigenschaft aktivieren, indem Sie das Inherits Flag festlegen. Die Eigenschaftsvererbung ist nützlich für Szenarien, in denen übergeordnete und untergeordnete Elemente eine gemeinsame Eigenschaft haben und es sinnvoll ist, dass das untergeordnete Element den übergeordneten Wert 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 Eigenschaftswertvererbung können Sie einen Datenkontext auf der Seite oder im Anwendungsstamm angeben, wodurch es nicht erforderlich ist, ihn für untergeordnete Elementbindungen anzugeben. Obwohl ein geerbter Eigenschaftswert den Standardwert außer Kraft setzt, können Eigenschaftswerte lokal für jedes untergeordnete Element festgelegt werden. Verwenden Sie die Eigenschaftswertvererbung sparsam, da sie Leistungskosten verursacht. Weitere Informationen finden Sie unter Eigenschaftswertvererbung.

  • Legen Sie das kennzeichen Journal fest, um anzugeben, dass Ihre Abhängigkeitseigenschaft von Navigationsjournaldiensten erkannt oder verwendet werden soll. Beispielsweise legt die SelectedIndex-Eigenschaft das Journal-Flag fest, um zu empfehlen, dass Anwendungen ein Journal der ausgewählten Elemente führen.

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. Beispielsweise ist IsMouseOver schreibgeschützt, da der Zustand nur durch Mauseingaben bestimmt werden sollte. Weitere Informationen finden Sie unter Schreibgeschützte Abhängigkeitseigenschaften.

Abhängigkeitseigenschaften des Sammlungstyps

Abhängigkeitseigenschaften vom Sammlungstyp weisen zusätzliche Implementierungsprobleme auf, z. B. das Festlegen eines Standardwerts für Referenztypen und die Unterstützung der Datenbindung für Elemente der Sammlung. 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 Zugriffsebene angeben, z. B. protected, kann weiterhin über den Bezeichner in Kombination mit Eigenschaftensystem-APIs auf eine Abhängigkeitseigenschaft zugegriffen werden. Sogar auf ein geschütztes Bezeichnerfeld kann über WPF-Metadatenberichterstellungs- oder Wertermittlungs-APIs wie LocalValueEnumeratorzugegriffen werden. Weitere Informationen finden Sie unter Sicherheit von Abhängigkeitseigenschaften.

Bei schreibgeschützten Abhängigkeitseigenschaften ist der Wert, den RegisterReadOnly zurückgibt, DependencyPropertyKey, und in der Regel machen Sie DependencyPropertyKey nicht zu einem public-Mitglied Ihrer Klasse. Da das WPF-Eigenschaftensystem die DependencyPropertyKey nicht über Ihren Code hinaus weitergibt, hat eine schreibgeschützte Abhängigkeitseigenschaft einen besseren set Schutz als eine schreibbare Abhängigkeitseigenschaft.

Abhängigkeitseigenschaften und Klassenkonstruktoren

Es gibt ein allgemeines Prinzip bei der Programmierung von verwaltetem Code, die häufig von Codeanalysetools erzwungen wird, dass Klassenkonstruktoren keine virtuellen Methoden aufrufen sollten. 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, kann vor abschluss der Initialisierung der abgeleiteten Klasse ausgeführt werden. Wenn Sie von einer Klasse ableiten, die bereits von DependencyObjectabgeleitet ist, ruft das Eigenschaftensystem selbst virtuelle Methoden intern auf und macht sie verfügbar. Diese virtuellen Methoden sind Teil der Dienste des WPF-Eigenschaftensystems. Durch das Überschreiben der Methoden können abgeleitete Klassen an der Wertermittlung teilnehmen. Um potenzielle Probleme mit der Laufzeitinitialisierung zu vermeiden, sollten Sie abhängigkeitseigenschaftswerte nicht innerhalb von Konstruktoren von Klassen festlegen, es sei denn, Sie folgen einem bestimmten Konstruktormuster. Weitere Informationen finden Sie unter sichere Konstruktor-Muster für DependencyObjects.

Siehe auch