Metadaten der Abhängigkeitseigenschaft
Das Windows Presentation Foundation (WPF)-Eigenschaftensystem enthält ein Metadatenberichterstattungssystem, 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 von der Klasse zugewiesen werden, die eine Abhängigkeitseigenschaft definiert, kann geändert werden, wenn die Abhängigkeitseigenschaft einer anderen Klasse hinzugefügt wird, und kann speziell von allen abgeleiteten Klassen außer Kraft gesetzt werden, die die Abhängigkeitseigenschaft von der definierenden Basisklasse erben.
Voraussetzungen
In diesem Thema wird davon ausgegangen, dass Sie Abhängigkeitseigenschaften aus der Perspektive eines Consumers vorhandener Abhängigkeitseigenschaften für WPF-Klassen verstehen und die Übersicht über Abhängigkeitseigenschaftengelesen haben. Um den Beispielen in diesem Thema zu folgen, sollten Sie auch XAML verstehen und wissen, wie WPF-Anwendungen geschrieben werden.
Verwendung von Abhängigkeitseigenschaftsmetadaten
Abhängigkeitseigenschaftsmetadaten sind als Objekt vorhanden, das abgefragt werden kann, um die Merkmale einer Abhängigkeitseigenschaft zu untersuchen. Auf diese Metadaten wird auch häufig vom Eigenschaftensystem zugegriffen, da sie jede gegebene Abhängigkeitseigenschaft 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. bestimmt werden kann. Eine ausführliche Erläuterung dazu, wie Standardwerte an der Rangfolge des Eigenschaftensystems beim Zuweisen von Werten für Abhängigkeitseigenschaften teilnehmen, finden Sie unter Dependency Property Value Precedence.
Verweise auf Callback-Implementierungen, die das Koerzions- oder Änderungsbenachrichtigungsverhalten auf Grundlage des Eigentümertyps beeinflussen. Beachten Sie, dass diese Rückrufe häufig mit einer nicht öffentlichen Zugriffsebene definiert sind, sodass das Abrufen der tatsächlichen Verweise aus Metadaten in der Regel nicht möglich ist, es sei denn, die Verweise befinden sich innerhalb Ihres zulässigen Zugriffsbereichs. Weitere Informationen zu Rückrufen von Abhängigkeitseigenschaften und Validierung finden Sie unter Rückrufe von Abhängigkeitseigenschaften und Validierung.
Wenn die fragliche Abhängigkeitseigenschaft als WPF-Framework-Eigenschaft betrachtet wird, enthalten die Metadaten möglicherweise Abhängigkeitseigenschaften auf WPF-Frameworkebene, die Informationen und den Status für Dienste wie das WPF-Framework-Layoutmodul und die Eigenschaftsvererbungslogik melden. Weitere Informationen zu diesem Aspekt der Metadaten von Abhängigkeitseigenschaften finden Sie unter Framework Property Metadata.
Metadaten-APIs
Der Typ, der die meisten Metadateninformationen bereitstellt, 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 selbst als Besitzer hinzufügen oder Metadaten außer Kraft setzen, die sie von der Definition der Abhängigkeitseigenschaft der Basisklasse erben. (Bei Fällen, 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 aus einer Abhängigkeitseigenschaft für eine DependencyObject Instanz abrufen.
Die PropertyMetadata Klasse wird dann abgeleitet, um spezifischere Metadaten für Architekturbereiche wie z. B. die WPF-Frameworkebenenklassen bereitzustellen. UIPropertyMetadata fügt Animationsberichterstattung hinzu und FrameworkPropertyMetadata stellt die im vorherigen Abschnitt erwähnten WPF-Framework-Eigenschaften bereit. Wenn Abhängigkeitseigenschaften registriert werden, können sie mit diesen PropertyMetadata abgeleiteten Klassen registriert werden. Wenn die Metadaten untersucht werden, kann der Basistyp PropertyMetadata möglicherweise zu den abgeleiteten Klassen umgewandelt werden, damit Sie die spezifischeren Eigenschaften untersuchen können.
Anmerkung
Die Eigenschaften, die in FrameworkPropertyMetadata angegeben werden können, werden in dieser Dokumentation manchmal als "Flags" bezeichnet. Wenn Sie neue Metadateninstanzen für die Verwendung bei Registrierungen von Abhängigkeitseigenschaften oder Metadatenüberschreibungen erstellen, geben Sie diese Werte mithilfe der flagweisen Enumeration FrameworkPropertyMetadataOptions an und übergeben dann möglicherweise verkettete Werte der Enumeration an den FrameworkPropertyMetadata-Konstruktor. Nach der Konstruktion werden diese Optionsmerkmale jedoch innerhalb einer FrameworkPropertyMetadata als eine Reihe boolescher Eigenschaften anstelle des konstruierenden Enumerationswerts verfügbar gemacht. Mit den booleschen Eigenschaften können Sie jede Bedingung überprüfen, anstatt eine Maske auf einen flagbasierten Enumerationswert anwenden zu müssen, um die Informationen abzurufen, an denen Sie interessiert sind. Der Konstruktor verwendet die verketteten FrameworkPropertyMetadataOptions, um die Länge der Konstruktorsignatur vernünftig zu halten, während die tatsächlich konstruierten Metadaten die diskreten Eigenschaften verfügbar machen, um die Abfrage der Metadaten intuitiver zu gestalten.
Wann Metadaten außer Kraft setzen, wann eine Klasse abgeleitet werden soll
Das WPF-Eigenschaftensystem verfügt über Funktionen zum Ändern einiger Eigenschaften von Abhängigkeitseigenschaften, ohne dass sie vollständig neu implementiert werden müssen. Um dies zu erreichen, wird eine andere Instanz von Eigenschaftsmetadaten für die Abhängigkeitseigenschaft erstellt, wie sie bei einem bestimmten Typ vorliegt. Beachten Sie, dass es sich bei den meisten vorhandenen Abhängigkeitseigenschaften nicht um virtuelle Eigenschaften handelt, und dass man sie bei geerbten Klassen, genau genommen, nur durch Überschattung des vorhandenen Elements erneut implementieren könnte.
Wenn das Szenario, das Sie für eine Abhängigkeitseigenschaft für einen Typ aktivieren möchten, nicht durch Ändern der Merkmale vorhandener Abhängigkeitseigenschaften erreicht werden kann, kann es erforderlich sein, eine abgeleitete Klasse zu erstellen und dann eine benutzerdefinierte Abhängigkeitseigenschaft für die abgeleitete Klasse zu deklarieren. Eine benutzerdefinierte Abhängigkeitseigenschaft verhält sich identisch mit Abhängigkeitseigenschaften, die von den WPF-APIs definiert werden. Weitere Details zu benutzerdefinierten Abhängigkeitseigenschaften finden Sie unter benutzerdefinierte Abhängigkeitseigenschaften.
Ein bemerkenswertes Merkmal einer Abhängigkeitseigenschaft, die Sie nicht außer Kraft setzen können, ist der Werttyp. Wenn Sie eine Abhängigkeitseigenschaft erben, die das ungefähre Verhalten aufweist, das Sie benötigen, aber einen anderen Typ dafür benötigen, müssen Sie eine benutzerdefinierte Abhängigkeitseigenschaft implementieren und die Eigenschaften möglicherweise über Typkonvertierung oder eine andere Implementierung für Ihre benutzerdefinierte Klasse verknüpfen. Außerdem können Sie kein vorhandenes ValidateValueCallbackersetzen, da dieses Callback im Registrierungsfeld selbst und nicht innerhalb seiner Metadaten vorhanden ist.
Szenarien zum Ändern vorhandener Metadaten
Wenn Sie mit Metadaten einer vorhandenen Abhängigkeitseigenschaft arbeiten, besteht ein häufiges Szenario zum Ändern der Metadaten von Abhängigkeitseigenschaften darin, den Standardwert zu ändern. Das Ändern oder Hinzufügen von Eigenschaftensystemrückrufen ist ein komplexeres Szenario. Sie möchten dies möglicherweise tun, wenn Ihre Implementierung einer abgeleiteten Klasse unterschiedliche Abhängigkeiten zwischen den Abhängigkeitseigenschaften aufweist. Eine der Voraussetzungen für ein Programmiermodell, das sowohl Code als auch deklarative Verwendung unterstützt, besteht darin, dass Eigenschaften die Festlegung in beliebiger Reihenfolge ermöglichen müssen. Daher müssen abhängige Eigenschaften ohne Kontext just-in-time festgelegt werden und können sich nicht darauf verlassen, eine Einstellungsreihenfolge zu kennen, z. B. in einem Konstruktor. Weitere Informationen zu diesem Aspekt des Eigenschaftensystems finden Sie unter Rückruffunktionen und Validierung von Abhängigkeitseigenschaften. Beachten Sie, dass Überprüfungsrückrufe nicht Teil der Metadaten sind; sie sind Teil des Bezeichners der Abhängigkeitseigenschaft. Daher können Überprüfungsrückrufe nicht geändert werden, indem die Metadaten überschrieben werden.
In einigen Fällen möchten Sie möglicherweise auch die Metadatenoptionen der WPF-Frameworkebene für vorhandene Abhängigkeitseigenschaften ändern. Diese Optionen kommunizieren bestimmte bekannte Bedingungen für Eigenschaften auf WPF-Frameworkebene mit anderen WPF-Framework-Prozessen wie dem Layoutsystem. Das Festlegen der Optionen erfolgt im Allgemeinen nur bei der Registrierung einer neuen Abhängigkeitseigenschaft, aber es ist auch möglich, die Metadaten der WPF-Framework-Eigenschaft als Teil eines OverrideMetadata- oder AddOwner-Aufrufs zu ändern. Die spezifischen Werte, die verwendet werden sollen, sowie weitere Informationen finden Sie unter Framework-Eigenschaftsmetadaten. Weitere Informationen, die für die Festlegung dieser Optionen für eine neu registrierte Abhängigkeitseigenschaft relevant sind, finden Sie unter Benutzerdefinierte Abhängigkeitseigenschaften.
Überschreiben von Metadaten
Der Zweck des Überschreibens von Metadaten besteht in erster Linie darin, dass Sie die Möglichkeit haben, die verschiedenen von den Metadaten abgeleiteten Verhaltensweisen zu ändern, die auf die Abhängigkeitseigenschaft angewendet werden, wie sie in Ihrem Typ definiert ist. Die Gründe hierfür werden im Abschnitt Metadaten ausführlicher erläutert. Weitere Informationen, einschließlich einiger Codebeispiele, finden Sie unter Überschreiben von Metadaten für eine Abhängigkeitseigenschaft.
Eigenschaftsmetadaten können während des Registrierungsaufrufs (Register) für eine Abhängigkeitseigenschaft bereitgestellt werden. In vielen Fällen sollten Sie jedoch typspezifische Metadaten für Ihre Klasse bereitstellen, wenn sie diese Abhängigkeitseigenschaft erbt. Sie können dies tun, indem Sie die OverrideMetadata-Methode aufrufen. Ein Beispiel aus den WPF-APIs ist die FrameworkElement Klasse, der Typ, der als erster die Focusable Abhängigkeitseigenschaft registriert. Die Control-Klasse überschreibt jedoch Metadaten für die Abhängigkeitseigenschaft, um einen eigenen anfänglichen Standardwert bereitzustellen, sie von false
in true
zu ändern und andernfalls die ursprüngliche Focusable Implementierung erneut zu verwenden.
Wenn Sie Metadaten außer Kraft setzen, werden die verschiedenen Metadatenmerkmale entweder zusammengeführt oder ersetzt.
PropertyChangedCallback wird zusammengeführt. Wenn Sie eine neue PropertyChangedCallbackhinzufügen, wird dieses Callback in den Metadaten gespeichert. Wenn Sie keine PropertyChangedCallback in der Überschreibung angeben, wird der Wert von PropertyChangedCallback als Verweis vom nächsten Vorgänger übernommen, der ihn in den Metadaten angegeben hat.
Das aktuelle Verhalten des Eigenschaftensystems für PropertyChangedCallback besteht darin, dass Implementierungen für alle Metadatenbesitzer in der Hierarchie erhalten und einer Tabelle hinzugefügt werden. Die Ausführungsreihenfolge durch das Eigenschaftensystem ist so festgelegt, dass die Callback-Funktionen der am weitesten abgeleiteten Klassen zuerst aufgerufen werden.
DefaultValue wird ersetzt. Wenn Sie in der Außerkraftsetzung keine DefaultValue angeben, kommt der Wert DefaultValue vom nächsten Vorgänger, der ihn in Metadaten angegeben hat.
CoerceValueCallback Implementierungen werden ersetzt. Wenn Sie eine neue CoerceValueCallbackhinzufügen, wird dieser Callback in den Metadaten gespeichert. Wenn Sie keine CoerceValueCallback in der Überschreibung angeben, wird der Wert von CoerceValueCallback als Verweis vom nächsten Vorgänger übernommen, der ihn in den Metadaten angegeben hat.
Das Verhalten des Eigenschaftensystems besteht darin, dass nur die CoerceValueCallback in den direkten Metadaten aufgerufen wird. Es werden keine Verweise auf andere CoerceValueCallback Implementierungen in der Hierarchie beibehalten.
Dieses Verhalten wird durch Mergeimplementiert und kann für abgeleitete Metadatenklassen außer Kraft gesetzt werden.
Das Überschreiben angefügter Eigenschaftsmetadaten
In WPF werden angefügte Eigenschaften als Abhängigkeitseigenschaften implementiert. Dies bedeutet, dass sie auch Eigenschaftsmetadaten haben, die einzelne Klassen überschreiben können. Die Bereichsüberlegungen bei einer angefügten Eigenschaft in WPF sind im Allgemeinen, dass jede DependencyObject eine angefügte Eigenschaft auf sich gesetzt haben kann. Daher kann jede DependencyObject abgeleitete Klasse die Metadaten für jede angefügte Eigenschaft überschreiben, da sie für eine Instanz der Klasse festgelegt werden kann. Sie können Standardwerte, Rückrufe oder WPF-Framework-charakteristische Berichtseigenschaften außer Kraft setzen. Wenn die angefügte Eigenschaft für eine Instanz Ihrer Klasse festgelegt ist, gelten diese Eigenschaftenmetadaten. Sie können zum Beispiel den Standardwert außer Kraft setzen, sodass Ihr Überschreibungswert als Wert der verbundenen Eigenschaft in Instanzen der Klasse gemeldet wird, sofern die Eigenschaft nicht anderweitig festgelegt wurde.
Anmerkung
Die Eigenschaft Inherits ist für angehängte Eigenschaften nicht relevant.
Hinzufügen einer Klasse als Besitzer einer vorhandenen Abhängigkeitseigenschaft
Eine Klasse kann sich mithilfe der AddOwner-Methode als Besitzer einer bereits registrierten Abhängigkeitseigenschaft hinzufügen. Dadurch kann die Klasse eine Abhängigkeitseigenschaft verwenden, die ursprünglich für einen anderen Typ registriert wurde. Die hinzufügende Klasse ist in der Regel keine abgeleitete Klasse des Typs, die diese Abhängigkeitseigenschaft zuerst als Besitzer registriert hat. Dies ermöglicht es Ihrer Klasse und den von ihr abgeleiteten Klassen, eine Implementierung von Abhängigkeitseigenschaften zu "erben", auch wenn die ursprüngliche Besitzerklasse und die hinzufügende Klasse nicht in derselben echten Klassenhierarchie stehen. Darüber hinaus kann die hinzufügende Klasse (und alle abgeleiteten Klassen) dann typspezifische Metadaten für die ursprüngliche Abhängigkeitseigenschaft bereitstellen.
Zusätzlich zum Hinzufügen als Eigentümer durch die Methoden des Eigenschaftensystems sollte die hinzufügende Klasse weitere öffentliche Mitglieder deklarieren, um die Abhängigkeitseigenschaft zu einem vollständigen Teilnehmer am Eigenschaftensystem zu machen, der sowohl mit Code als auch mit Markup interagiert. Eine Klasse, die eine vorhandene Abhängigkeitseigenschaft hinzufügt, hat die gleichen Verantwortlichkeiten hinsichtlich der Bereitstellung des Objektmodells für diese Abhängigkeitseigenschaft wie eine Klasse, die eine neue benutzerdefinierte Abhängigkeitseigenschaft definiert. Das erste Element, das freigegeben werden soll, ist ein Abhängigkeitseigenschafts-Identifikatorfeld. Dieses Feld sollte ein public static readonly
Feld vom Typ DependencyPropertysein, das dem Rückgabewert des AddOwner Aufrufs zugewiesen ist. Das zweite Element, das definiert werden soll, ist die CLR-Eigenschaft "Wrapper" (Common Language Runtime). Der Wrapper macht es wesentlich bequemer, Ihre Abhängigkeitseigenschaft im Code zu bearbeiten (Sie vermeiden jedes Mal Aufrufe an SetValue und können diesen Aufruf nur einmal im Wrapper selbst ausführen). Der Wrapper wird genauso implementiert, wie er implementiert würde, wenn Sie eine benutzerdefinierte Abhängigkeitseigenschaft registrieren würden. 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 von der Besitzerklasse als angehängte Eigenschaft definiert ist. Im Allgemeinen besteht der Grund dafür darin, die zuvor angefügte Eigenschaft als vom Anfügen unabhängige Abhängigkeitseigenschaft darzustellen. Anschließend exponieren Sie den AddOwner-Rückgabewert als ein public static readonly
-Feld, um ihn als Abhängigkeitseigenschaftsbezeichner zu verwenden, und definieren entsprechende "Wrapper"-Eigenschaften, sodass die Eigenschaft in der Membertabelle erscheint und eine nicht angefügte Verwendung in Ihrer Klasse unterstützt.
Siehe auch
.NET Desktop feedback