Benutzerdefinierte Abhängigkeitseigenschaften

Dieses Thema beschreibt die Gründe, warum Anwendungsentwickler und Komponentenautoren in 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.

Voraussetzungen

In diesem Thema wird vorausgesetzt, dass Sie sich mit Abhängigkeitseigenschaften aus Sicht von vorhandenen Abhängigkeitseigenschaften von Consumern in WPF-Klassen auskennen, und dass Sie das Thema Übersicht über Abhängigkeitseigenschaften gelesen haben. Um den Beispielen in diesem Thema zu folgen, sollten Sie zudem XAML verstehen und wissen, wie WPF-Anwendungen geschrieben werden.

Was ist eine Abhängigkeitseigenschaft?

Was andernfalls eine Common Language Runtime (CLR)-Eigenschaft wäre, die Formatierung, Datenbindung, Vererbung und Animationen sowie Standardwerte unterstützt, wird hier durch die Implementierung als Abhängigkeitseigenschaft aktiviert. Abhängigkeitseigenschaften sind Eigenschaften, die durch den Aufruf der Register-Methode (oder RegisterReadOnly) im WPF-Eigenschaftssystem registriert werden und die durch ein DependencyProperty-Bezeichnerfeld unterstützt werden. Abhängigkeitseigenschaften können nur von DependencyObject-Typen verwendet werden. DependencyObject steht jedoch sehr weit oben in der Klassenhierarchie von WPF, daher kann die Mehrheit der in WPF verfügbaren Klassen Abhängigkeitseigenschaften unterstützen. Weitere Informationen zu Abhängigkeitseigenschaften und zur Terminologie und den Konventionen für die Beschreibung in SDK finden Sie unter Übersicht über Abhängigkeitseigenschaften.

Beispiele für Abhängigkeitseigenschaften

Beispiele für Abhängigkeitseigenschaften, die in WPF-Klassen implementiert sind, sind die Background-Eigenschaft, die Width-Eigenschaft und die Text-Eigenschaft, neben vielen anderen. Jede Abhängigkeitseigenschaft, die von einer Klasse verfügbar gemacht wird, hat ein entsprechendes öffentliches statisches Feld des Typs DependencyProperty, das für dieselbe Klasse verfügbar gemacht wird. Es handelt sich um den Bezeichner für die Abhängigkeitseigenschaft. Der Name des Bezeichners wird nach einer Konvention gewählt: Der Name der Abhängigkeitseigenschaft mit der angefügten Zeichenfolge Property. Zum Beispiel lautet das entsprechende DependencyProperty-Bezeichnerfeld für die BackgroundEigenschaft BackgroundProperty. Der Bezeichner speichert die Informationen zur Abhängigkeitseigenschaft zum Zeitpunkt der Registrierung. Der Bezeichner wird später für andere Vorgänge verwendet, die die Abhängigkeitseigenschaft betreffen, z.B. das Aufrufen von SetValue.

Wie in Übersicht über Abhängigkeitseigenschaften erwähnt, sind alle Abhängigkeitseigenschaften in WPF (mit Ausnahme der meisten angefügten Eigenschaften) aufgrund der „Wrapper“-Implementierung auch CLR-Eigenschaften. Daher können Sie über Code Abhängigkeitseigenschaften abrufen oder festlegen, indem Sie CLR-Accessoren aufrufen, die die Wrapper in der Art definieren, in der Sie auch andere CLR-Eigenschaften verwenden würden. Als Verbraucher von etablierten Abhängigkeitseigenschaften verwenden Sie normalerweise nicht die DependencyObject-Methoden GetValue und SetValue, die den Verbindungspunkt zum zugrunde liegenden Eigenschaftssystem darstellen. Vielmehr hat die bestehende Implementierung der CLR-Eigenschaften bereits GetValue und SetValue innerhalb der get und set Wrapper-Implementierungen der Eigenschaft aufgerufen und dabei das Bezeichnerfeld entsprechend verwendet. Wenn Sie eine benutzerdefinierte Abhängigkeitseigenschaft selbst implementieren, definieren Sie den Wrapper auf ähnliche Weise.

Wann sollten Sie eine Abhängigkeitseigenschaft implementieren?

Wenn Sie eine Eigenschaft für eine Klasse implementieren, haben Sie die Möglichkeit, Ihre Eigenschaft mit einem DependencyProperty-Bezeichner zu sichern, solange Ihre Klasse von DependencyObject abgeleitet wird, und sie so zu einer Abhängigkeitseigenschaft zu machen. Es ist nicht immer notwendig oder angemessen, Ihre Eigenschaft in eine Abhängigkeitseigenschaft umzuwandeln. Es hängt von den Anforderungen Ihres Szenarios ab. Manchmal ist die normale Technik des Sicherns der Eigenschaft mit einem privaten Feld ausreichend. Sie sollten Ihre Eigenschaft allerdings als Abhängigkeitseigenschaft implementieren, wenn Sie möchten, dass Ihre Eigenschaft eine oder mehrere der folgenden WPF-Funktionen unterstützt:

  • Sie möchten, dass Ihre Eigenschaft in einem Stil festgelegt werden kann. Weitere Informationen finden Sie unter Erstellen von Formaten und Vorlagen.

  • Sie möchten, dass die Eigenschaft Datenbindung unterstützt. Weitere Informationen zur Datenbindung mit Abhängigkeitseigenschaften finden Sie unter Binden der Eigenschaften von zwei Steuerelementen.

  • Sie möchten, dass die Eigenschaft mit einem dynamischen Ressourcenverweis festgelegt werden kann. Weitere Informationen finden Sie unter XAML-Ressourcen.

  • Sie möchten einen Eigenschaftswert automatisch von einem übergeordneten Element in der Elementstruktur erben. In diesem Fall registrieren Sie sich bei der RegisterAttached-Methode, auch wenn Sie eine Eigenschaftsumhüllung für den CLR-Zugriff erstellen. Weitere Informationen finden Sie unter Vererbung von Eigenschaftswerten.

  • Sie möchten, dass Ihre Eigenschaft animiert werden kann. Weitere Informationen finden Sie unter Übersicht über Animation.

  • 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. 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. Ein verwandtes Konzept ist die Koersion des Eigenschaftswerts. Weitere Informationen finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften.

  • Sie möchten geltende Konventionen für Metadaten verwenden, die auch von WPF-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. Oder Sie möchten Überschreibungen von Metadaten verwenden, sodass abgeleitete Klassen auf Metadaten basierende Eigenschaften, z.B. den Standardwert, ändern können.

  • Sie möchten, dass Eigenschaften von benutzerdefinierten Steuerelementen Unterstützung von Visual Studio WPF Designer erhalten, z. B. das Bearbeiten des Fensters Eigenschaften. Weitere Informationen finden Sie unter Übersicht über das Erstellen von Steuerelementen.

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. 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 Eigenschaften finden Sie unter Metadaten für Abhängigkeitseigenschaften.

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

Das Definieren einer Abhängigkeitseigenschaft besteht aus vier unterschiedlichen Konzepten. Diese Konzepte sind nicht unbedingt aufeinanderfolgende Schritte, da einige von ihnen am Ende als einzelne Codezeilen in der Implementierung kombiniert werden:

  • (Optional) Erstellen Sie Eigenschaftsmetadaten für die Abhängigkeitseigenschaft.

  • Registrieren Sie den Eigenschaftennamen im Eigenschaftensystem, indem Sie einen Besitzertyp und den Typ des Eigenschaftswerts angeben. Geben Sie, falls verwendet, auch die Metadaten der Eigenschaft an.

  • Definieren Sie einen DependencyProperty-Bezeichner als ein Feld vom Typ public static readonly des Besitzertyps.

  • Definieren Sie eine CLR-„Wrapper“-Eigenschaft, deren Name mit dem Namen der Abhängigkeitseigenschaft übereinstimmt. Implementieren Sie die get- und set-Accessoren der CLR-„Wrapper“-Eigenschaft, um eine Verbindung mit der Abhängigkeitseigenschaft herzustellen, die sie sichert.

Registrieren der Eigenschaft im Eigenschaftensystem

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. Bei diesen Vorgängen kann es sich um interne Vorgänge oder um Ihr eigenes durch Code aufgerufenes Eigenschaftensystem APIs handeln. Zum Registrieren der Eigenschaft rufen Sie die Methode Register innerhalb des Texts der Klasse auf (innerhalb der Klasse, aber außerhalb von Memberdefinitionen). Der Bezeichner wird auch vom Register-Methodenaufruf als Rückgabewert bereitgestellt. Der Aufruf von Register erfolgt außerhalb von Memberdefinitionen, da Sie diesen Rückgabewert verwenden, um ein public static readonly-Feld vom Typ DependencyProperty als Teil Ihrer Klasse zu erstellen und zuzuweisen. Das Feld wird zum Bezeichner für Ihre Abhängigkeitseigenschaft.

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ängigkeitseigenschaften

Es gibt Namenskonventionen für Abhängigkeitseigenschaften, die Sie bis auf bestimmte Ausnahmefälle befolgen müssen.

Die Abhängigkeitseigenschaft selbst hat einen einfachen Namen, z.B. „AquariumGraphic“ wie in diesem Beispiel, der als erster Parameter von Register angegeben wird. Dieser Name muss innerhalb jedes Registrierungstyps eindeutig sein. Abhängigkeitseigenschaften, die über Basistypen geerbt werden, gelten bereits als teil des Registrierungstyps. Namen von geerbten Eigenschaften können nicht erneut registriert werden. 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.

Geben Sie einem Bezeichnerfeld beim Erstellen den Namen der Eigenschaft bei der Registrierung und das Suffix Property. Dieses Feld ist Ihr Bezeichner für die Abhängigkeitseigenschaft und wird später als Eingabe für die Aufrufe von SetValue und GetValue verwendet, die Sie in den Wrappern durchführen werden, entweder über allen anderen Codezugriff auf die Eigenschaft über ihren eigenen Code, jeden externen Codezugriff, den Sie zulassen, über das Eigenschaftensystem und möglicherweise über XAML-Prozessoren.

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.

Implementieren des „Wrappers“

Ihre Wrapper-Implementierung sollte GetValue in der get-Implementierung aufrufen, und SetValue in der set-Implementierung (der ursprüngliche Registrierungsaufruf und das Feld werden hier zur Verdeutlichung ebenfalls angezeigt).

Außer in Ausnahmefällen sollten Ihre Wrapper-Implementierungen nur die GetValue- und SetValue-Aktionen bzw. ausführen. Der Grund hierfür wird im Thema Laden von XAML und Abhängigkeitseigenschaften erläutert.

Alle vorhandenen öffentlichen Abhängigkeitseigenschaften, die für die WPF-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.


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 entsprechend der Konvention wieder identisch mit dem ausgewählten und als erster Parameter des Register-Aufrufs gegebenen Namen sein, mit dem die Eigenschaft registriert wurde. Wenn die Eigenschaft den Konventionen nicht folgt, werden dadurch nicht unbedingt alle möglichen Verwendungsarten deaktiviert, aber Sie werden mehrere deutliche Probleme bemerken:

  • Bestimmte Aspekte von Stilen und Vorlagen funktionieren nicht.

  • Die meisten Tools und Designer verlassen sich auf Benennungskonventionen, um XAML ordnungsgemäß zu serialisieren oder 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.

Eigenschaftsmetadaten für eine neue Abhängigkeitseigenschaft

Wenn Sie eine Abhängigkeitseigenschaft registrieren, wird bei der Registrierung über das Eigenschaftensystem ein Metadatenobjekt erstellt, das Merkmale der Eigenschaft speichert. Viele dieser Merkmale verfügen über Standardwerte, die bei der Registrierung der Eigenschaft mit einfachen Signaturen von Register festgelegt werden. Andere Signaturen von Register ermöglichen es Ihnen, die bei der Registrierung der Eigenschaft gewünschten Metadaten anzugeben. 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.

Wenn Sie eine Abhängigkeitseigenschaft erstellen, die in einer abgeleiteten Klasse von FrameworkElement existiert, können Sie die spezialisiertere Metadatenklasse FrameworkPropertyMetadata anstelle der Basisklasse PropertyMetadata verwenden. Der Konstruktor für die Klasse FrameworkPropertyMetadata verfügt über mehrere Signaturen, in denen Sie verschiedene Metadateneigenschaften in Kombination angeben können. Verwenden Sie die Signatur, die nur einen einzelnen Parameter vom Typ Object annimmt, wenn Sie nur den Standardwert angeben möchten. Übergeben Sie diesen Objektparameter als typspezifischen Standardwert für Ihre Eigenschaft (der angegebene Standardwert muss der Typ sein, den Sie als propertyType-Parameter im Register-Aufruf angegeben haben).

Für FrameworkPropertyMetadata können Sie auch Metadaten-Optionsflags für Ihre Eigenschaft angeben. 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.

Festlegen von Flags für die entsprechenden Metadaten

  • Wenn Ihre Eigenschaft (oder die Änderung ihres Wertes) die Benutzeroberfläche (UI) beeinflusst, und insbesondere die Art und Weise, wie das Layoutsystem die Größe Ihres Elements in einer Seite darstellen soll, setzen Sie einen oder mehrere der folgenden Flags: AffectsMeasure, AffectsArrange, AffectsRender.

    • AffectsMeasure gibt an, dass eine Änderung dieser Eigenschaft eine Änderung am Rendering von UI erfordert, wobei das enthaltende Objekt möglicherweise mehr oder weniger Platz innerhalb des übergeordneten Elements benötigt. Für die Eigenschaft „Breite“ sollte beispielsweise dieses Flag festgelegt sein.

    • AffectsArrange gibt an, dass eine Änderung an dieser Eigenschaft eine Änderung am Rendering von UI erfordert, das normalerweise keine Änderung am dedizierten Bereich erfordert. Es wird aber angegeben, dass sich die Positionierung innerhalb des Bereichs geändert hat. Für die Eigenschaft „Ausrichtung“ sollte beispielsweise dieses Flag festgelegt sein.

    • AffectsRender gibt an, dass eine andere Änderung aufgetreten ist, die keine Auswirkung auf Layout und Maße hat, aber erneutes Rendern erfordert. Ein Beispiel wäre eine Eigenschaft, die eine Farbe eines vorhandenen Elements ändert, z.B. „Hintergrund“.

    • Diese Flags werden in Metadaten häufig als ein Protokoll für Ihre eigenen Überschreibungsimplementierungen von Eigenschaftensystem oder Layoutrückrufen verwendet. Sie könnten zum Beispiel einen OnPropertyChanged-Rückruf haben, der InvalidateArrange aufruft, wenn eine Eigenschaft der Instanz eine Wertänderung meldet und AffectsArrange als true in ihren Metadaten steht.

  • 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. Ein Beispiel ist die Eigenschaft MinOrphanLines, die im Flussdokumentmodell verwendet wird, in dem Änderungen an dieser Eigenschaft das allgemeine Rendering des Flussdokuments mit dem Absatz beeinflussen kann. Verwenden Sie AffectsParentArrange oder AffectsParentMeasure, um ähnliche Fälle in Ihren eigenen Immobilien zu identifizieren.

  • Standardmäßig unterstützen Abhängigkeitseigenschaften die Datenbindung. 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.

  • Standardmäßig ist die Datenbindung Mode für Abhängigkeitseigenschaften standardmäßig auf OneWay. Sie können die Bindung pro Bindungsinstanz jederzeit in TwoWay ändern. Weitere Informationen hierzu finden Sie unter Angeben der Bindungsrichtung. Als Autor der Abhängigkeitseigenschaft können Sie aber auch auswählen, dass die Eigenschaft standardmäßig die Bindungsmethode TwoWay verwendet. Ein Beispiel für eine bestehende Abhängigkeitseigenschaft ist MenuItem.IsSubmenuOpen; das Szenario für diese Eigenschaft ist, dass die IsSubmenuOpen-Einstellungslogik und das Compositing MenuItem von mit dem Standarddesign interagieren. Die Eigenschaftslogik IsSubmenuOpen verwendet die Datenbindung nativ zum Aufrechterhalten des Status der Eigenschaft in Übereinstimmung mit anderen Zustandseigenschaften und Methodenaufrufen. Eine weitere Beispieleigenschaft, die standardmäßig TwoWay bindet, ist TextBox.Text.

  • Sie können auch die Eigenschaftenvererbung in einer benutzerdefinierten Abhängigkeitseigenschaft aktivieren, indem Sie das Flag Inherits festlegen. 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. Ein Beispiel für eine vererbbare Eigenschaft ist DataContext, die für Bindungsvorgänge verwendet wird, um das wichtige Master/Detail-Szenario für die Datenanzeige zu aktivieren. Durch die Vererbbarkeit von DataContext erben alle untergeordneten Elemente diesen Datenkontext ebenfalls. 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. DataContext ist ein gutes Beispiel, um zu veranschaulichen, dass die Vererbung den Standardwert überschreibt, aber immer lokal auf ein bestimmtes untergeordnetes Element angewendet werden kann. Weitere Informationen hierzu finden Sie unter Verwenden des Master-/Detailmusters mit hierarchischen Daten. 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.

  • Legen Sie das Flag Journal so fest, dass es angibt, wenn Ihre Abhängigkeitseigenschaft ermittelt werden oder von Navigations-Journaling-Diensten verwendet werden soll. Ein Beispiel ist die Eigenschaft SelectedIndex. Ein ausgewähltes Element in einem Auswahl-Steuerelement sollte beibehalten werden, wenn durch die Journaling-Historie navigiert wird.

Schreibgeschützte Abhängigkeitseigenschaften

Sie können eine Abhängigkeitseigenschaft definieren, die schreibgeschützt ist. 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. Weitere Informationen finden Sie unter Schreibgeschützte Abhängigkeitseigenschaften.

Abhängigkeitseigenschaften vom Auflistungstyp

Bei Abhängigkeitseigenschaften vom Auflistungstyp gibt es zusätzliche Implementierungsprobleme, die man berücksichtigen sollte. Weitere Informationen finden Sie unter Abhängigkeitseigenschaften vom Auflistungstyp.

Überlegungen zur Sicherheit von Abhängigkeitseigenschaften

Abhängigkeitseigenschaften sollten als öffentliche Eigenschaften deklariert werden. Bezeichnerfelder für Abhängigkeitseigenschaften sollten als öffentliche statische Felder deklariert werden. Auch wenn Sie versuchen, andere Zugriffsebenen zu deklarieren (z.B. geschützt), kann auf eine Abhängigkeitseigenschaft über den Bezeichner in Kombination mit dem Eigenschaftensystem APIs zugegriffen werden. Sogar auf ein geschütztes Bezeichnerfeld kann möglicherweise durch APIs für Berichterstellung für Metadaten oder Festlegen von Werten zugegriffen werden, die ein Teil des Eigenschaftensystems sind, z. B. LocalValueEnumerator. Weitere Informationen finden Sie unter Sicherheit von Abhängigkeitseigenschaften.

Abhängigkeitseigenschaften und Klassenkonstruktoren

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. 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. Beim Ableiten von einer Klasse, die bereits von DependencyObject abgeleitet wird, sollten Sie sich im Klaren darüber sein, 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 sehr 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