Metadaten für Abhängigkeitseigenschaften

Das Eigenschaftssystem von Windows Presentation Foundation (WPF) umfasst ein Metadatenberichtssystem, das über das hinausgeht, was über eine Eigenschaft durch Reflexion oder allgemeine CLR-Merkmale (Common Language Runtime) berichtet werden kann. Metadaten für eine Abhängigkeitseigenschaft können auch eindeutig durch die Klasse zugewiesen werden, die eine Abhängigkeitseigenschaft definiert, sie können geändert werden, wenn die Abhängigkeitseigenschaft zu einer anderen Klasse hinzugefügt wird, und sie können gezielt von allen abgeleiteten Klassen überschrieben werden, die die Abhängigkeitseigenschaft von der definierenden Basisklasse erben.

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 Ü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.

So werden Metadaten für Abhängigkeitseigenschaften genutzt

Metadaten für Abhängigkeitseigenschaften sind ein Objekt vorhanden, das zur Untersuchung der Eigenschaften einer Abhängigkeitseigenschaft abgefragt werden kann. Auch das Eigenschaftensystem greift häufig auf diese Metadaten zu, da es alle Abhängigkeitseigenschaften verarbeitet. Das Metadatenobjekt für eine Abhängigkeitseigenschaft kann die folgenden Informationstypen enthalten:

  • Standardwert für die Abhängigkeitseigenschaft, wenn kein anderer Wert für die Abhängigkeitseigenschaft durch lokalen Wert, Stil, Vererbung usw. ermittelt werden kann. Eine ausführliche Beschreibung der Beteiligung von Standardwerten an der Rangfolge, die das Eigenschaftssystem bei der Zuweisung von Werten für Abhängigkeitseigenschaften verwendet, finden Sie unter Vorrang der Werte von Abhängigkeitseigenschaften.

  • Verweise auf die Rückrufimplementierungen, die das Umwandlungs- oder Änderungsbenachrichtigungsverhalten pro Besitzertyp beeinflussen. Beachten Sie, dass diese Rückrufe häufig auf nicht öffentlicher Zugriffsebene definiert werden. Die tatsächlichen Verweise aus den Metadaten zu erhalten, ist im Allgemeinen nicht möglich, wenn die Verweise sich nicht innerhalb Ihres zulässigen Zugriffsbereichs befinden. Weitere Informationen zu Abhängigkeitseigenschaftenrückrufen finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften.

  • Wenn die fragliche Abhängigkeitseigenschaft eine Eigenschaft auf WPF-Frameworkebene ist, enthalten die Metadaten möglicherweise Merkmale der Abhängigkeitseigenschaft auf WPF-Frameworkebene, die Informationen und Zustände von Diensten wie der WPF-Framework-Layout-Engine und Eigenschaftsvererbungslogik melden. Weitere Informationen zu diesem Aspekt der Metadaten für Abhängigkeitseigenschaften finden Sie unter Framework-Eigenschaftenmetadaten.

Metadaten-APIs

Der Typ, der den Großteil der vom Eigenschaftensystem verwendeten Metadateninformationen meldet, ist die PropertyMetadata-Klasse. Metadateninstanzen werden optional angegeben, wenn Abhängigkeitseigenschaften im Eigenschaftensystem registriert werden, und können erneut für zusätzliche Typen angegeben werden, die sich selbst entweder als Besitzer hinzufügen oder Metadaten überschreiben, die sie von der Basisklasse der Definition der Abhängigkeitseigenschaften erben. (Für Fälle, in denen eine Eigenschaftsregistrierung keine Metadaten angibt, wird ein Standard PropertyMetadata mit Standardwerten für diese Klasse erstellt.) Die registrierten Metadaten werden als PropertyMetadata zurückgegeben, wenn Sie die verschiedenen GetMetadata-Überladungen aufrufen, die Metadaten von einer Abhängigkeitseigenschaft für eine DependencyObject-Instanz abrufen.

Die PropertyMetadata-Klasse wird dann abgeleitet, um spezifischere Metadaten für Architekturaspekte wie die Klassen auf WPF-Frameworkebene bereitzustellen. UIPropertyMetadata fügt Animationsberichte hinzu, und FrameworkPropertyMetadata stellt die im vorherigen Abschnitt erwähnten WPF-Eigenschaften auf Frameworkebene bereit. Wenn Abhängigkeitseigenschaften registriert werden, können sie mit diesen von PropertyMetadata abgeleiteten Klassen registriert werden. Wenn die Metadaten untersucht werden, wird der Basistyp PropertyMetadata ggf. in die abgeleiteten Klassen umgewandelt werden, damit Sie die spezifischeren Eigenschaften prüfen können.

Hinweis

Die Eigenschaftenmerkmale, die in FrameworkPropertyMetadata angegeben werden können, werden in dieser Dokumentation manchmal als „Flags“ bezeichnet. Geben Sie beim Erstellen neuer Metadateninstanzen für die Registrierung von Abhängigkeitseigenschaften oder dem Überschreiben von Metadaten diese Werte mithilfe der Flag-Enumeration FrameworkPropertyMetadataOptions an, und stellen Sie dann dem FrameworkPropertyMetadata-Konstruktor möglicherweise verkettete Werte der Enumeration bereit. Allerdings werden diese Optioneneigenschaften, sobald sie erstellt wurden, innerhalb von FrameworkPropertyMetadata als eine Reihe von booleschen Eigenschaften und nicht als der erstellende Enumerationswert verfügbar gemacht. Mit den booleschen Eigenschaften können Sie jede Bedingung überprüfen, anstatt eine Maske auf einen Flag-Enumerationswert anzuwenden, um die interessanten Informationen abzurufen. Der Konstruktor verwendet die verketteten FrameworkPropertyMetadataOptions, um die Länge der Konstruktorsignatur sinnvoll zu begrenzen, während die eigentlichen erstellten Metadaten die diskreten Eigenschaften verfügbar machen, die die Abfrage der Metadaten intuitiver gestalten.

Überschreiben von Metadaten und Ableiten einer Klasse

Das WPF-Eigenschaftensystem verfügt über Funktionen zum Ändern einiger Merkmale von Abhängigkeitseigenschaften, ohne dass sie vollständig neu implementiert werden müssen. Dies geschieht durch das Erstellen einer anderen Instanz von Metadaten für die Abhängigkeitseigenschaft, wie sie auf einem bestimmten Typ vorhanden ist. Beachten Sie, dass die meisten vorhandenen Abhängigkeitseigenschaften keine virtuellen Eigenschaften sind. Ihre „Neuimplementierung“ in geerbten Klassen könnte also nur das Shadowing des vorhandenen Elements erreicht werden.

Wenn das Szenario, das Sie für eine Abhängigkeitseigenschaft auf einem Typ umsetzen möchten, durch eine Änderung der Eigenschaften vorhandener Abhängigkeitseigenschaften nicht erreicht werden kann, müssen Sie möglicherweise eine abgeleitete Klasse erstellen und dann auf die abgeleitete Klasse eine benutzerdefinierte Abhängigkeitseigenschaft deklarieren. Eine benutzerdefinierte Abhängigkeitseigenschaft verhält sich genauso wie die von WPF-APIs definierten Abhängigkeitseigenschaften. Weitere Informationen zu benutzerdefinierten Abhängigkeitseigenschaften finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.

Ein wichtiges Merkmal einer Abhängigkeitseigenschaft, das überschrieben werden kann, ist der Werttyp. Wenn Sie eine Abhängigkeitseigenschaft erben, die ungefähr das erforderliche Verhalten, aber einen anderen Typ aufweist, müssen Sie eine benutzerdefinierte Abhängigkeitseigenschaft implementieren und die Eigenschaften möglicherweise über die Typkonvertierung oder eine andere Implementierung auf Ihrer Klasse verknüpfen. Darüber hinaus kann kein vorhandener ValidateValueCallback ersetzt werden, da dieser Rückruf im Registrierungsfeld selbst und nicht innerhalb der Metadaten vorhanden ist.

Szenarios zum Ändern vorhandener Metadaten

Wenn Sie mit den Metadaten einer vorhandenen Abhängigkeitseigenschaft arbeiten, besteht ein häufiges Szenario für die Änderung der Metadaten der Abhängigkeitseigenschaft in der Änderung des Standardwerts. Das Ändern oder Hinzufügen von Eigenschaftensystemrückrufen ist ein erweitertes Szenario. Wenn Ihre Implementierung einer abgeleiteten Klasse verschiedene Wechselbeziehungen zwischen Abhängigkeitseigenschaften aufweist, ist dieses Szenario möglicherweise hilfreich. Eine der Voraussetzungen eines Programmiermodells, das sowohl Code als auch deklarative Verwendung unterstützt, ist die Möglichkeit, Eigenschaften in einer beliebigen Reihenfolge festzulegen. Daher müssen alle abhängigen Eigenschaften Just-In-Time ohne Kontext festgelegt werden und dürfen sich nicht auf die Kenntnis einer Festlegungsreihenfolge verlassen, wie z.B. in einem Konstruktor. Weitere Informationen zu diesem Aspekt des Eigenschaftensystems finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften. Beachten Sie, dass Überprüfungsrückrufe kein Teil der Metadaten sind. Sie gehören zum Bezeichner der Abhängigkeitseigenschaft. Aus diesem Grund können Überprüfungsrückrufe nicht durch das Überschreiben der Metadaten geändert werden.

In einigen Fällen möchten Sie möglicherweise auch die Eigenschaftenmetadatenoptionen auf WPF-Frameworkebene für vorhandene Abhängigkeitseigenschaften ändern. Diese Optionen kommunizieren bestimmte bekannte Bedingungen zu Eigenschaften auf WPF-Frameworkebene an andere Prozesse auf WPF-Frameworkebene wie das Layoutsystem. Das Festlegen der Optionen erfolgt in der Regel nur beim Registrieren einer neuen Abhängigkeitseigenschaft, aber es ist auch möglich, die Metadaten der WPF-Eigenschaft auf Frameworkebene als Teil eines OverrideMetadata- oder AddOwner-Aufrufs zu ändern. Die genauen Werte, die verwendet werden müssen, und weitere Informationen finden Sie unter Framework-Eigenschaftenmetadaten. Weitere Informationen zu Festlegung dieser Optionen für neu registrierte Abhängigkeitseigenschaften finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.

Überschreiben von Metadaten

Metadaten werden in erster Linie überschrieben, damit Sie die verschiedenen, von Metadaten abgeleiteten Verhaltensweisen ändern können, die auf die Abhängigkeitseigenschaft, so wie sie auf Ihrem Typ vorhanden ist, angewendet werden. Die Gründe hierfür werden ausführlicher im Abschnitt Metadaten erläutert. Weitere Informationen und Codebeispiele finden Sie unter Überschreiben von Metadaten für eine Abhängigkeitseigenschaft.

Eigenschaftenmetadaten können für eine Abhängigkeitseigenschaft während des Registrierungsaufrufs bereitgestellt werden (Register). In vielen Fällen stellen Sie jedoch typspezifische Metadaten für Ihre Klasse bereit, wenn sie die Abhängigkeitseigenschaft erbt. Hierfür rufen Sie die OverrideMetadata-Methode auf. In einem Beispiel aus den WPF-APIs ist die Klasse FrameworkElement der Typ, der zuerst die Abhängigkeitseigenschaft Focusable registriert. Die Control-Klasse überschreibt jedoch die Metadaten der Abhängigkeitseigenschaft, um einen eigenen Standardwert bereitzustellen. Der Wert wird dabei von false in true geändert und verwendet andernfalls die ursprüngliche Focusable-Implementierung wieder.

Wenn Sie Metadaten überschreiben, werden die verschiedenen Metadateneigenschaften entweder zusammengeführt oder ersetzt.

  • PropertyChangedCallback wird zusammengeführt. Wenn Sie einen neuen PropertyChangedCallback hinzufügen, wird dieser Rückruf in den Metadaten gespeichert. Wenn Sie in der Überschreibung keinen PropertyChangedCallback angeben, wird der Wert von PropertyChangedCallback als Verweis von dem nächsten Vorfahren, der ihn in den Metadaten angegeben hat, höher gestuft.

  • Das Verhalten des tatsächlichen Eigenschaftensystems für PropertyChangedCallback besteht darin, dass die Implementierungen für alle Metadaten in der Hierarchie beibehalten und einer Tabelle hinzugefügt werden, wobei nach der Ausführungsreihenfolge des Eigenschaftensystems der am stärksten abgeleitete Rückruf einer Klasse zuerst aufgerufen wird.

  • DefaultValue wird ersetzt. Wenn Sie in der Überschreibung keinen DefaultValue angeben, stammt der Wert von DefaultValue aus dem nächsten Vorfahren, der ihn in den Metadaten angegeben hat.

  • CoerceValueCallback-Implementierungen werden ersetzt. Wenn Sie einen neuen CoerceValueCallback hinzufügen, wird dieser Rückruf in den Metadaten gespeichert. Wenn Sie in der Überschreibung keinen CoerceValueCallback angeben, wird der Wert von CoerceValueCallback als Verweis von dem nächsten Vorfahren, der ihn in den Metadaten angegeben hat, höher gestuft.

  • Das Eigenschaftssystem verhält sich so, dass nur der CoerceValueCallback in den unmittelbaren Metadaten aufgerufen wird. Es werden keine Verweise auf andere CoerceValueCallback-Implementierungen in der Hierarchie beibehalten.

Dieses Verhalten wird von Merge implementiert und kann für abgeleitete Metadatenklassen überschrieben werden.

Überschreiben von Metadaten der angefügten Eigenschaft

Angefügte Eigenschaften werden in WPF als Abhängigkeitseigenschaften implementiert. Dies bedeutet, dass sie auch Metadaten besitzen, die von einzelnen Klassen überschrieben werden können. Die Bereichsüberlegungen für eine angefügte Eigenschaft in WPF sind im Allgemeinen, dass jedes DependencyObject eine angefügte Eigenschaft haben kann, die auf das Objekt festgelegt wurde. Aus diesem Grund kann jede von DependencyObject abgeleitete Klasse die Metadaten für eine beliebige angefügte Eigenschaft überschreiben, da dies möglicherweise für eine Instanz der Klasse festgelegt wurde. Sie können Standardwerte, Rückrufe oder Eigenschaften der Berichterstattung über Merkmale auf WPF-Frameworkebene überschreiben. Wenn die angefügte Eigenschaft auf eine Instanz Ihrer Klasse festgelegt ist, finden diese Merkmale zum Überschreiben von Metadateneigenschaften Anwendung. Falls die Eigenschaft nicht anderweitig festgelegt ist, können Sie z.B. den Standardwert überschreiben, sodass der Überschreibungswert als der Wert der angefügten Eigenschaft auf Ihren Klasseninstanzen gemeldet wird.

Hinweis

Die Inherits-Eigenschaft ist für angefügte Eigenschaften nicht relevant.

Hinzufügen einer Klasse als Besitzer einer vorhandenen Abhängigkeitseigenschaft

Eine Klasse kann sich selbst mithilfe der AddOwner-Methode als Besitzer einer Abhängigkeitseigenschaft hinzufügen, die bereits registriert wurde. Dadurch kann die Klasse eine Abhängigkeitseigenschaft verwenden, die ursprünglich für einen anderen Typ registriert wurde. Die hinzugefügte Klasse ist in der Regel keine abgeleitete Klasse des Typs, der die Abhängigkeitseigenschaft zuerst als Besitzer registriert hat. Aus diesem Grund kann die Klasse und ihre abgeleiteten Klassen eine Implementierung von Abhängigkeitseigenschaften ohne die ursprüngliche Besitzerklasse „erben“, und ohne dass die hinzufügende Klasse der gleichen echten Klassenhierarchie angehört. Darüber hinaus kann die hinzufügende Klasse (und auch alle abgeleiteten Klassen) typspezifische Metadaten für die ursprüngliche Abhängigkeitseigenschaft bereitstellen.

Die hinzufügende Klasse sollte sich nicht nur über die Hilfsprogrammmethoden des Eigenschaftensystems als Besitzer hinzufügen, sondern auch weitere öffentliche Member für sich selbst deklarieren, um die Abhängigkeitseigenschaft in einen vollständigen Bestandteil des Eigenschaftensystems zu verwandeln, der für Code und Markup verfügbar ist. Eine Klasse, die eine vorhandene Abhängigkeitseigenschaft hinzufügt, hat beim Verfügbarmachen des Objektmodells für die Abhängigkeitseigenschaft die gleichen Aufgaben wie eine Klasse, die eine neue benutzerdefinierte Abhängigkeitseigenschaft definiert. Der erste Member, der verfügbar gemacht wird, ist ein Bezeichnerfeld für die Abhängigkeitseigenschaft. Dieses Feld sollte ein public static readonly-Feld vom Typ DependencyProperty sein, das dem Rückgabewert des AddOwner-Aufrufs zugewiesen wird. Der zweite zu definierende Member ist die „Wrapper“-Eigenschaft der CLR ( Common Language Runtime). Der Wrapper erleichtert das Bearbeiten Ihre Abhängigkeitseigenschaften im Code (Aufrufe von SetValue werden immer vermieden, und der Aufruf wird nur ein Mal im Wrapper selbst durchgeführt). Der Wrapper wird genauso implementiert, wie dies auch beim Registrieren einer benutzerdefinierten Abhängigkeitseigenschaft der Fall wäre. Weitere Informationen zum Implementieren einer Abhängigkeitseigenschaft finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften und Hinzufügen eines Besitzertyps für eine Abhängigkeitseigenschaft.

AddOwner und angefügte Eigenschaften

Sie können AddOwner für eine Abhängigkeitseigenschaft aufrufen, die durch die Besitzerklasse als angefügte Eigenschaft definiert wurde. Der Zweck liegt im Allgemeinen darin, die zuvor angefügte Eigenschaft als nicht angefügte Abhängigkeitseigenschaft verfügbar zu machen. Machen Sie dann den Rückgabewert AddOwner als ein public static readonly-Feld für die Verwendung als Bezeichner für die Abhängigkeitseigenschaft verfügbar, und definieren Sie anschließend die entsprechenden Wrapper-Eigenschaften, sodass die Eigenschaft in der Membertabelle erscheint und die Verwendung nicht angefügter Eigenschaften in Ihrer Klasse unterstützt.

Weitere Informationen