Featureanbieter und Featureverbindungen
Jedes entwurfsfähige Objekt in einer WPF- (Windows Presentation Foundation) oder Silverlight-Anwendung kann eine beliebige Anzahl von Designer-Erweiterungen verfügbar machen. Im folgenden Thema werden die Funktionen von Featureanbietern und die Rolle von Featureverbindungen beim Bereitstellen von Entwurfszeitfeatures erläutert.
Grundlagen der Featureanbieter und Featureverbindungen
Ein Featureanbieter ist ein einfacher Typ, der zusätzliche Entwurfszeitfunktionalität für ein Objekt bereitstellt. Manche Featureanbieter stellen lediglich Informationen zu Unterkomponenten bereit und erfordern keine Aktion durch den Designer. Andere Featureanbieter fügen dem Designer-Kontextmenü des Objekts möglicherweise Menüelemente hinzu oder erstellen benutzerdefinierte Adorner zum Ändern der Größe bzw. zum Bearbeiten, oder sie erstellen eine neue Definition für das Verschieben von Objekten per Drag & Drop im Designer.
Featureanbieter werden entweder durch eine direkte Ableitung von der FeatureProvider-Klasse implementiert oder von einer Klasse, die selbst von FeatureProvider abgeleitet wird, beispielsweise AdornerProvider und ContextMenuProvider. Featureanbieter werden im Hinblick auf Einfachheit entwickelt und sollten nicht versuchen, Zustandsdaten zwischen Instanzen zu speichern.
Eine Featureverbindung verwaltet einen oder mehrere Featureanbieter für ein gegebenes Objekt. Featureverbindungen können neue Dienste über einen Diensteanbieter veröffentlichen und Designerereignisse überwachen (beispielsweise Auswahländerungen). Featureverbindungen werden implementiert, indem Sie eine neue Klasse von der FeatureConnector<TFeatureProviderType>-Klasse oder der PolicyDrivenFeatureConnector<TFeatureProviderType>-Klasse ableiten.
Featureanbieter
Ein Featureanbieter soll ein einfacher Erweiterungspunkt sein. In den häufigsten Szenarien zur Designer-Erweiterbarkeit wird vorzugsweise von vorhandenen Featureanbieterklassen abgeleitet, statt neue Featureverbindungen zu erstellen. Featureanbieter dürfen keine Zustandsdaten speichern, da sie mehrmals erstellt und zerstört werden.
Featureanbieter werden vollständig von Featureverbindungen verwaltet und mithilfe von Metadaten Objekten zugeordnet, insbesondere mithilfe von FeatureAttribute. Aus diesen Metadaten ermittelt die Featureverbindung FeatureProvider-Typen. Die FeatureManager-Klasse identifiziert die erforderliche Featureverbindung für jeden ermittelten Featureanbieter.
Zu den allgemeinen Implementierungen von Featureanbietern gehören Auswahladorner, Verben und Eigenschaften-Editoren. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Erstellen eines Entwurfszeitadorners.
Beispiele für Featureanbieter
In der folgenden Abbildung werden ein visueller Designer und alle Typen von Features gezeigt, die zur Kategorie Featureanbieter oder Featureverbindung gehören. Beachten Sie, dass es sich bei der Abbildung lediglich um ein Beispiel dafür handelt, wie einige der Features eines Designers implementiert werden könnten.
In der folgenden Tabelle werden die Featureanbieter aufgeführt, von denen Sie ableiten können.
Featureanbieter |
Beschreibung |
---|---|
Fügt der Oberfläche des Designers Adorner hinzu. |
|
Fügt Adorner hinzu, die für die primäre Auswahl angezeigt werden. |
|
Definiert einen Satz von Menüelementen, die in einem Kontextmenü angezeigt werden. |
|
Definiert einen Satz von Menüelementen, der für die aktuelle Auswahl angezeigt wird. |
|
PolicyDrivenFeatureConnector<TFeatureProviderType>.ItemFeatureProvider |
Identifiziert die Featureanbieter, die zu einem bestimmten Element gehören. |
Fügt dem aktiven Tool Aufgaben hinzu. |
|
Stellt eine Reihe von Aufgaben im Markierungstool zur Verfügung, wenn sich eine Klasse in der primären Auswahl befindet. |
|
Fasst Eigenschaftenänderungen zusammen, die vom Benutzer im Designer vorgenommen werden, und stellt neue Werte zur Entwurfszeit bereit. |
Wie Featureanbieter zur Entwurfszeit erstellt werden
In vielen Fällen müssen Sie keine eigenen benutzerdefinierten Featureverbindungen erstellen. Sie können einen Featureanbieter erstellen und ihn mit dem FeatureConnectorAttribute direkt einer Klasse zuordnen. Die FeatureManager-Klasse ist die Komponente des WPF-Designer, die Featureanbieter aktiviert. FeatureManager untersucht die Metadaten eines Objekts, sobald es auf der Entwurfsoberfläche platziert wird. Wenn es ein FeatureConnectorAttribute für ein Objekt findet, erstellt es den zugeordneten Featureanbieter.
Wenn Sie beispielsweise einen Adorner erstellen möchten, mit dem Sie den Headertext eines benutzerdefinierten Steuerelements direkt auf der Entwurfsoberfläche bearbeiten können, implementieren Sie den Adorner, indem Sie ihn vom PrimarySelectionAdornerProvider ableiten, der wiederum vom FeatureProvider abgeleitet wird. Danach ordnen Sie mit dem FeatureConnectorAttribute dem Steuerelement den benutzerdefinierten Adorner zu.
Zuordnen von Featureanbietern zu Typen
Ein Entwurfszeittool ordnet mithilfe von Metadatenattributen Featureanbietern Typen zu. Es muss eine deklarative Art geben, Metadaten an die tatsächlichen Laufzeitobjekte oder die Instanzen zu binden. Diese Bindung ist auf Toolebene erforderlich und ist nicht Aufgabe eines Entwurfszeitframeworks. Die folgende Illustration zeigt, wie ein Entwurfszeittool Featureanbieter an verschiedene Typen anfügt.
Es gibt in der WPF-Designer-Architektur zwei Möglichkeiten, Featureanbieter an Typen anzufügen: der FeatureAttribute-Typ und der FeatureConnectorAttribute-Typ. Der FeatureAttribute-Typ wird für Typen oder Instanzen von bearbeitbaren Objekten verwendet und macht eine Eigenschaft verfügbar, die einen FeatureProvider darstellt.
Das FeatureConnectorAttribute ergänzt eine FeatureProvider-Klasse und gibt an, welcher Typ von Featureverbindung zum Hosten des angegebenen Featureanbieters erforderlich ist. Die FeatureManager-Klasse erstellt die erforderlichen FeatureConnector<TFeatureProviderType>-Instanzen, wenn Sie Objekte ändern, die an sie übergeben werden.
Stellen Sie sich einen WPF-spezifischen Designer vor, in dem die bearbeitbaren Objekte vom Typ UIElement sind. Ein solches Tool verwendet möglicherweise "Ziehpunkte", um Begrenzungen von einzelnen Elementen zu ergänzen. Diese Adorner stellen eine Auswahl visuell dar und ermöglichen die Manipulation dieser bearbeitbaren Objekte. Der Designer ordnet allen Objekten des Typs UIElement über Metadaten ein Ziehpunktfeature zu. Die folgende Abbildung zeigt, wie ein Designer einen Ziehpunktanbieter an ein UIElement auf der Entwurfsoberfläche anfügen kann.
Wenn ein UIElement vorhanden ist und zur Analyse an den Feature-Manager übergeben wird, wird der GrabHandleProvider durch die dem UIElement zugewiesenen Metadaten ermittelt. Der GrabHandleProvider-Typ selbst oder sein Basistyp wird mithilfe von Metadaten geprüft, um die erforderliche Featureverbindung zu bestimmen.
Featureverbindungen
Bei Featureverbindungen handelt es sich um die unterste Ebene der Erweiterbarkeit, die von dieser Architektur verfügbar gemacht wird. Featureverbindungen werden erstellt, wenn ein Verweis auf einen EditingContext vorhanden ist. Featureverbindungen können globale Dienste abonnieren und ihre eigenen Dienste hinzufügen. Die abstrakte FeatureConnector<TFeatureProviderType>-Klasse implementiert die IDisposable-Schnittstelle, die eine einfache Bereinigungsstrategie beinhaltet.
Featureverbindungen werden nach Bedarf erstellt. Wenn der FeatureManager ein FeatureConnectorAttribute in einem FeatureProvider ermittelt, erstellt er den angegebenen FeatureConnector<TFeatureProviderType>, wenn dieser Typ nicht bereits vorhanden ist. Statt einen Standardsatz von Featureverbindungen beim Start einer Designersitzung zu erstellen, werden Featureverbindungen nur dann erstellt, wenn sie ermittelt werden. Wenn es mehr als einen FeatureConnectorAttribute-Typ für einen FeatureProvider gibt, werden alle Featureverbindungen initialisiert. Dies ermöglicht es einem Drittanbieter, von einem vorhandenen FeatureProvider abzuleiten, eine benutzerdefinierte Featureverbindung hinzuzufügen und beide Funktionalitätssätze initialisieren zu lassen.
Die meisten Funktionen der FeatureConnector<TFeatureProviderType>-Klasse sind in der geschützten CreateFeatureProviders-Methode implementiert. Die Übergabe eines Objekts an diese Methode bewirkt, dass vom Featureconnector das Objekt nach FeatureAttribute-Typen durchsucht wird. Wenn solche Attribute gefunden werden, wird eine dem jeweiligen Attribut zugeordnete FeatureProvider-Instanz erstellt und in einer Liste zurückgegeben.
Die FeatureConnector<TFeatureProviderType>-Basisklasse ist generisch und verwendet den Typ des Featureanbieters, den der FeatureConnector<TFeatureProviderType> hostet. Featureanbieter verwenden ein FeatureConnectorAttribute, um die zugeordnete Featureverbindung anzugeben. Geschützte Basisklassenmethoden von FeatureConnector<TFeatureProviderType>, vor allem die CreateFeatureProviders-Methode, können typisierte Auflistungen von Featureanbietern an die abgeleiteten Featureverbindungen zurückgeben, wobei für die abgeleiteten Klassen die Umwandlung und Typsicherheit nicht beachtet werden muss.
Erstellen von benutzerdefinierten Featureverbindungen
Wenn Sie Designerereignisse, wie z. B. die Auswahl, überwachen möchten, müssen Sie eine eigene Featureverbindung erstellen. Leiten Sie von der FeatureConnector<TFeatureProviderType>-Klasse oder der PolicyDrivenFeatureConnector<TFeatureProviderType>-Klasse ab, um die benutzerdefinierte Designerlogik zu implementieren.
Featureverbindungen werden als Verweis an den globalen EditingContext des Designers übergeben, durch den die Featureverbindung auf Designerdienste zugreifen und ihre eigenen benutzerdefinierten Dienste veröffentlichen kann. Ein Diagrammsteuerelementanbieter möchte beispielsweise einen Dienst veröffentlichen, der es einem benutzerdefinierten Typ-Editor im Designer ermöglicht, alle aktuell im Diagramm enthaltenen Widgets aufzulisten.
Wenn Sie eine von FeatureConnector<TFeatureProviderType> abgeleitete Klasse erstellt haben, können Sie sie einem Featureanbieter zuordnen, indem Sie das FeatureConnectorAttribute auf den Featureanbieter anwenden. Immer dann, wenn eine Instanz dieses Featureanbieters erstellt wird, überprüft der FeatureManager die Metadaten für das FeatureConnectorAttribute. Wenn das Attribut definiert ist und derzeit keine Instanz des zugeordneten FeatureConnector<TFeatureProviderType> ausgeführt wird, wird es vom FeatureManager erstellt, und alle zukünftigen Instanzen dieses Featureanbieters werden mit dem FeatureConnector<TFeatureProviderType> verknüpft.
Codebeispiele zur Implementierung eines Featureanbieters finden Sie unter Gewusst wie: Erstellen einer benutzerdefinierten Featureverbindung.