Metadaten für Abhängigkeitseigenschaften
Aktualisiert: November 2007
Das Windows Presentation Foundation (WPF)-Eigenschaftensystem enthält ein Metadatenberichtssystem, das mehr als nur die Daten von Eigenschaften berichtet, indem die Reflektion verwendet oder allgemeine common language runtime (CLR)-Merkmale angegeben werden. Die Metadaten für eine Abhängigkeitseigenschaft können auch eindeutig von der Klasse zugewiesen werden, die eine Abhängigkeitseigenschaft definiert, sie können geändert werden, wenn die Abhängigkeitseigenschaft einer anderen Klasse hinzugefügt wird, und sie können von allen abgeleiteten Klassen spezifisch überschrieben werden, die die Abhängigkeitseigenschaft von der definierenden Basisklasse erben.
Dieses Thema enthält folgende Abschnitte.
- Vorbereitungsmaßnahmen
- Verwenden von Metadaten für Abhängigkeitseigenschaften
- Metadaten-APIs
- Wann werden Metadaten überschrieben und wann wird eine Klasse abgeleitet?
- Szenarios zum Ändern vorhandener Metadaten
- Verwandte Abschnitte
Vorbereitungsmaßnahmen
In diesem Thema wird vorausgesetzt, dass Sie sich aus Sicht eines Consumers vorhandener Abhängigkeitseigenschaften in Windows Presentation Foundation (WPF)-Klassen auskennen und die Übersicht über Abhängigkeitseigenschaften gelesen haben. Um den Beispielen in diesem Thema folgen zu können, sollten Sie außerdem mit der Verwendung von XAML und dem Schreiben von WPF-Anwendungen vertraut sein.
Verwenden von Metadaten für Abhängigkeitseigenschaften
Metadaten für Abhängigkeitseigenschaften sind als Objekt vorhanden, das Sie abfragen können, um die Merkmale einer Abhängigkeitseigenschaft zu erhalten. Auf diese Metadaten wird häufig auch vom Eigenschaftensystem zugegriffen, während es die jeweiligen Abhängigkeitseigenschaften verarbeitet. Das Metadatenobjekt für eine Abhängigkeitseigenschaft kann die folgenden Arten von Informationen enthalten:
Standardwert für die Abhängigkeitseigenschaft, wenn für die Abhängigkeitseigenschaft basierend auf lokalem Wert, Stil, Vererbung usw. kein anderer Wert ermittelt werden kann. Ausführliche Informationen dazu, wo Standardwerte in der vom Eigenschaftensystem verwendeten Rangfolge beim Zuweisen von Werten für Abhängigkeitseigenschaften stehen, finden Sie unter Priorität von Abhängigkeitseigenschaftenwerten.
Verweise auf Rückrufimplementierungen, die sich auf die Koersion oder auf Änderungsbenachrichtigungsverhalten pro Besitzer auswirken. Beachten Sie, dass diese Rückrufe häufig mit einer nicht öffentlichen Zugriffsebene definiert werden. Das Abrufen der eigentlichen Verweise aus den Metadaten ist also im Allgemeinen nicht möglich, es sei denn, die Verweise liegen im zulässigen Zugriffsbereich. Weitere Informationen zu Rückrufen von Abhängigkeitseigenschaften finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften.
Wenn die fragliche Abhängigkeitseigenschaft als Eigenschaft auf WPF-Frameworkebene angesehen wird, enthalten die Metadaten ggf. Merkmale von WPF-Frameworkebene-Abhängigkeitseigenschaften, die die Informationen und Zustände von Diensten wie dem WPF-Frameworkebene-Layoutmodul und der Eigenschaftenvererbungslogik berichten. Weitere Informationen zu diesem Aspekt der Metadaten für Abhängigkeitseigenschaften finden Sie unter Framework-Eigenschaftenmetadaten.
Metadaten-APIs
Der Typ, der die meisten Metadateninformationen berichtet, die vom Eigenschaftensystem verwendet werden, ist die PropertyMetadata-Klasse. Metadateninstanzen werden optional angegeben, wenn Abhängigkeitseigenschaften beim Eigenschaftensystem registriert werden, und können erneut für zusätzliche Typen angegeben werden, die sich entweder selbst als Besitzer hinzufügen oder die Metadaten überschreiben, die sie von der Abhängigkeitseigenschaftendefinition der Basisklasse erben. (In Fällen, in denen eine Eigenschaftenregistrierung keine Metadaten angibt, werden standardmäßige PropertyMetadata mit Standardwerten für die jeweilige Klasse erstellt.) Die registrierten Metadaten werden als PropertyMetadata zurückgegeben, wenn Sie die verschiedenen GetMetadata-Überladungen aufrufen, die Metadaten von einer Abhängigkeitseigenschaft einer DependencyObject-Instanz abrufen.
Die PropertyMetadata-Klasse wird dann abgeleitet, um spezifischere Metadaten für Architekturaspekte bereitzustellen, z. B. WPF-Frameworkebene-Klassen. UIPropertyMetadata fügt ein Animationsberichtssystem hinzu, und FrameworkPropertyMetadata stellt die WPF-Frameworkebene-Eigenschaften bereit, die im vorherigen Abschnitt erwähnt wurden. Wenn Abhängigkeitseigenschaften registriert werden, können dabei diese abgeleiteten PropertyMetadata-Klassen verwendet werden. Wenn die Metadaten untersucht werden, kann der PropertyMetadata-Basistyp ggf. in die abgeleiteten Klassen umgewandelt werden, damit Sie die spezifischeren Eigenschaften prüfen können.
Tipp
Die Eigenschaftenmerkmale, die in FrameworkPropertyMetadata angegeben werden können, werden in dieser Dokumentation auch als "Flags" bezeichnet. Beim Erstellen von neuen Metadateninstanzen zur Verwendung in Abhängigkeitseigenschaft-Registrierungen oder Metadatenüberschreibungen geben Sie diese Werte an, indem Sie die Flag-Enumeration FrameworkPropertyMetadataOptions verwenden und potenziell verkettete Werte der Enumeration dem FrameworkPropertyMetadata-Konstruktor bereitstellen. Nach der Erstellung werden diese Optionsmerkmale jedoch innerhalb eines FrameworkPropertyMetadata-Elements als eine Serie boolescher Eigenschaften offengelegt, nicht der Enumerationswert der Erstellung. Mithilfe der booleschen Eigenschaften können Sie die einzelnen bedingten Elemente überprüfen, anstatt eine Maske auf einen Wert der Flag-Enumeration anwenden zu müssen, um die gewünschten Informationen zu erhalten. Der Konstruktor verwendet das verkette FrameworkPropertyMetadataOptions-Element, um die Länge der Konstruktorsignatur auf ein angemessenes Maß zu begrenzen. Die erstellten Metadaten legen jedoch die diskreten Eigenschaften offen, um das Abfragen der Metadaten intuitiver zu gestalten.
Wann werden Metadaten überschrieben und wann wird eine Klasse abgeleitet?
Das WPF-Eigenschaftensystem verfügt über Funktionen zum Ändern einiger Merkmale von Abhängigkeitseigenschaften, ohne dass dabei eine neue Implementierung erforderlich ist. Dies wird erreicht, indem für die Abhängigkeitseigenschaft eine andere Instanz der Eigenschaftenmetadaten als die erstellt wird, die für einen bestimmten Typ vorhanden ist. Beachten Sie, dass es sich bei den meisten vorhandenen Abhängigkeitseigenschaften nicht um virtuelle Eigenschaften handelt, also kann eine "Neuimplementierung" für geerbte Klassen streng genommen nur erreicht werden, indem der vorhandene Member gespiegelt wird (Shadowing).
Wenn das Szenario, das Sie für eine Abhängigkeitseigenschaft eines Typs aktivieren möchten, sich nicht erreichen lässt, indem Sie die Merkmale vorhandener Abhängigkeitseigenschaften ändern, kann es erforderlich sein, dass Sie eine abgeleitete Klasse erstellen. Anschließend müssen Sie für die abgeleitete Klasse dann eine benutzerdefinierte Abhängigkeitseigenschaft deklarieren. Eine benutzerdefinierte Abhängigkeitseigenschaft verhält sich genauso wie Abhängigkeitseigenschaften, die von WPF-APIs definiert werden. Weitere Informationen zu benutzerdefinierten Abhängigkeitseigenschaften finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.
Ein wichtiges Merkmal einer Abhängigkeitseigenschaft, das Sie nicht überschreiben können, ist ihr Werttyp. Wenn Sie eine Abhängigkeitseigenschaft erben, die nahezu über das gewünschte Verhalten verfügt, Sie jedoch einen anderen Typ benötigen, müssen Sie eine benutzerdefinierte Abhängigkeitseigenschaft implementieren und die Eigenschaften ggf. mithilfe einer Typumwandlung oder einer anderen Implementierung für Ihre benutzerdefinierte Klasse verknüpfen. Außerdem können Sie einen vorhandenen ValidateValueCallback nicht ersetzen, da dieser Rückruf im Registrierungsfeld selbst vorhanden ist, nicht innerhalb der Metadaten.
Szenarios zum Ändern vorhandener Metadaten
Wenn Sie mit den Metadaten einer vorhandenen Abhängigkeitseigenschaft arbeiten, besteht ein gängiges Szenario zum Ändern von Metadaten einer Abhängigkeitseigenschaft darin, den Standardwert zu ändern. Das Ändern oder Hinzufügen von Eigenschaftensystemrückrufen ist ein erweitertes Szenario. Sie können dies in Erwägung ziehen, wenn Ihre Implementierung einer abgeleiteten Klasse zwischen Abhängigkeitseigenschaften über verschiedene Beziehungen verfügt. Eine der Bedingungen bei der Verwendung eines Programmiermodells, das sowohl Code als auch die deklarative Nutzung unterstützt, besteht darin, dass Eigenschaften in beliebiger Reihenfolge festgelegt werden können. Aus diesem Grund müssen alle abhängigen Eigenschaften erst bei Bedarf (just in time) ohne Kontext festgelegt werden, ohne dass eine Reihenfolge für die Festlegung bekannt ist, z. B. wie bei einem Konstruktor. Weitere Informationen zu diesem Aspekt von Eigenschaftensystemen finden Sie unter Rückrufe und Validierung von Abhängigkeitseigenschaften. Beachten Sie, dass es sich bei Validierungsrückrufen nicht um einen Teil der Metadaten handelt. Sie sind Teil des Bezeichners einer Abhängigkeitseigenschaft. Deshalb können Sie Validierungsrückrufe nicht ändern, indem Sie die Metadaten überschreiben.
Es kann vorkommen, dass Sie für vorhandene Abhängigkeitseigenschaften auch die Eigenschaftenmetadatenoptionen der WPF-Frameworkebene ändern müssen. Diese Optionen kommunizieren bekannte Bedingungen von Eigenschaften der WPF-Frameworkebene an andere Prozesse der WPF-Frameworkebene, z. B. an das Layoutsystem. Das Festlegen der Optionen wird in der Regel nur beim Registrieren einer neuen Abhängigkeitseigenschaft vorgenommen. Es ist jedoch auch möglich, die Eigenschaftenmetadaten der WPF-Frameworkebene als Teil eines OverrideMetadata- oder AddOwner-Aufrufs zu ändern. Die spezifischen Werte und weitere Informationen finden Sie unter Framework-Eigenschaftenmetadaten. Weitere Informationen dazu, wie Sie diese Optionen für neu registrierte Abhängigkeitseigenschaften festlegen müssen, finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.
Überschreiben von Metadaten
Der Zweck des Überschreibens von Metadaten besteht vor allem darin, Ihnen die Möglichkeit zu geben, die verschiedenen von den Metadaten abgeleiteten Verhalten zu ändern, die auf die auf Ihrem Typ basierende Abhängigkeitseigenschaft angewendet werden. Die Gründe hierfür werden im Abschnitt Metadaten näher erläutert. Weitere Informationen und Codebeispiele finden Sie unter Gewusst wie: Überschreiben von Metadaten für eine Abhängigkeitseigenschaft.
Sie können Eigenschaftenmetadaten für eine Abhängigkeitseigenschaft während des Registrierungsaufrufs angeben (Register). In vielen Fällen ist es jedoch ratsam, für Ihre Klasse typspezifische Metadaten anzugeben, wenn diese die Abhängigkeitseigenschaft erbt. Sie erreichen dies, indem Sie die OverrideMetadata-Methode aufrufen. In einem Beispiel mit WPF-APIs ist die FrameworkElement-Klasse der Typ, der die Focusable-Abhängigkeitseigenschaft zuerst registriert. Die Control-Klasse überschreibt Metadaten für die Abhängigkeitseigenschaft jedoch, um ihren eigenen Anfangsstandardwert anzugeben, indem dieser von false in true geändert wird, und verwendet andernfalls die ursprüngliche Focusable-Implementierung.
Wenn Sie Metadaten überschreiben, werden die einzelnen Metadatenmerkmale 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 des nächsten Vorgängers höher gestuft, der diesen in den Metadaten angegeben hat.
Das eigentliche Verhalten des Eigenschaftensystems für PropertyChangedCallback besteht darin, dass Implementierungen für alle Metadatenbesitzer in der Hierarchie beibehalten und der Tabelle hinzugefügt werden. Für das Eigenschaftensystem gilt die Ausführungsreihenfolge, dass Rückrufe der am stärksten abgeleiteten Klasse zuerst aufgerufen werden.
DefaultValue wird ersetzt. Wenn Sie in der Überschreibung keinen PropertyChangedCallback angeben, stammt der Wert von DefaultValue vom nächsten Vorgänger, der diesen 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 des nächsten Vorgängers höher gestuft, der diesen in den Metadaten angegeben hat.
Das Verhalten des Eigenschaftensystems besteht darin, 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 der Metadaten von angefügten Eigenschaften
In WPF werden angefügte Eigenschaften als Abhängigkeitseigenschaften implementiert. Dies bedeutet, dass sie auch über Eigenschaftenmetadaten verfügen, die einzelne Klassen überschreiben können. Die Bereichsüberlegungen für eine angefügte Eigenschaft in WPF gehen in der Regel dahin, dass für alle DependencyObject-Elemente eine angefügte Eigenschaft festgelegt werden kann. Aus diesem Grund können alle abgeleiteten DependencyObject-Klassen die Metadaten für eine angefügte Eigenschaft überschreiben, da die Festlegung für eine Instanz der Klasse erfolgen kann. Sie können Standardwerte, Rückrufe oder WPF-Frameworkebene-Eigenschaften zum Berichten von Merkmalen überschreiben. Wenn die angefügte Eigenschaft für eine Instanz Ihrer Klasse festgelegt wird, gelten diese überschriebenen Eigenschaftenmetadaten-Merkmale. Sie können z. B. den Standardwert überschreiben, damit der Überschreibungswert für Instanzen Ihrer Klasse als Wert der angefügten Eigenschaft berichtet wird, solange die Eigenschaft nicht anderweitig eingerichtet wurde.
Tipp
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 als Besitzer einer Abhängigkeitseigenschaft hinzufügen, die bereits registriert wurde, indem sie die AddOwner-Methode verwendet. Auf diese Weise kann die Klasse eine Abhängigkeitseigenschaft verwenden, die ursprünglich für einen anderen Typ registriert wurde. Bei der hinzufügenden Klasse handelt es sich normalerweise nicht um eine abgeleitete Klasse des Typs, der die Abhängigkeitseigenschaft als Besitzer zuerst registriert hat. Ihre Klasse und die dazugehörigen abgeleiteten Klassen können also eine Abhängigkeitseigenschaft-Implementierung "erben", ohne dass sich die ursprüngliche Besitzerklasse und die hinzufügende Klasse in derselben "wahren" Klassenhierarchie befinden. Außerdem kann die hinzufügende Klasse (sowie auch alle abgeleiteten Klassen) für die ursprüngliche Abhängigkeitseigenschaft dann typspezifische Metadaten bereitstellen.
Zusätzlich dazu, dass sich die Klasse über die entsprechenden Methoden des Eigenschaftensystems selbst als Besitzer hinzufügt, sollte die hinzufügende Klasse für sich selbst weitere öffentliche Member deklarieren, um die Abhängigkeitseigenschaft zu einem vollständigen Teilnehmer am Eigenschaftensystem zu machen, der sowohl per Code als auch per Markup zugänglich ist. Eine Klasse, die eine vorhandene Abhängigkeitseigenschaft hinzufügt, verfügt in Bezug auf das Offenlegen des Objektmodells für die jeweilige Abhängigkeitseigenschaft über dieselben Zuständigkeiten wie eine Klasse, die eine neue benutzerdefinierte Abhängigkeitseigenschaft definiert. Der erste Member, der offengelegt wird, ist ein Abhängigkeitseigenschaft-Bezeichnerfeld. Dieses Feld sollte ein public static readonly-Feld vom Typ DependencyProperty sein, das dem Rückgabewert des AddOwner-Aufrufs zugewiesen ist. Der zweite zu definierende Member ist die common language runtime (CLR)-Wrappereigenschaft. Der Wrapper erleichtert es Ihnen erheblich, Ihre Abhängigkeitseigenschaft per Code zu bearbeiten (Sie vermeiden jeweils Aufrufe von SetValue, denn Sie müssen diesen Aufruf nur einmal im Wrapper selbst durchführen). Der Wrapper wird genauso implementiert, wie dies auch beim Registrieren einer benutzerdefinierten Abhängigkeitseigenschaft der Fall wäre. Weitere Informationen zur Implementierung einer Abhängigkeitseigenschaft finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften und Gewusst wie: 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 von der Besitzerklasse als angefügte Eigenschaft definiert ist. Der Grund hierfür ist normalerweise, dass die vorherige angefügte Eigenschaft als nicht angefügte Abhängigkeitseigenschaft offengelegt werden soll. Anschließend legen Sie den AddOwner-Rückgabewert als public static readonly-Feld für die Verwendung als Abhängigkeitseigenschaftbezeichner offen und definieren geeignete Wrappereigenschaften, so dass die Eigenschaft in der Membertabelle erscheint und die Verwendung nicht angefügter Eigenschaften in Ihrer Klasse unterstützt.
Siehe auch
Konzepte
Übersicht über Abhängigkeitseigenschaften
Framework-Eigenschaftenmetadaten