Partager via


Architecture de l'extensibilité du concepteur WPF

Mise à jour : novembre 2007

Le Concepteur Windows Presentation Foundation (WPF) pour Visual Studio est un environnement d'édition visuelle des contrôles composites WPF, implémentés par le type UserControl. Le Concepteur WPF est basé sur une infrastructure possédant une architecture extensible que vous pouvez étendre pour créer votre propre expérience de design personnalisée.

En étendant le modèle objet du Concepteur WPF, vous pouvez personnaliser l'apparence et le comportement au moment du design de contenu de WPF avec une liberté remarquable. Par exemple, vous pouvez étendre le Concepteur WPF des façons suivantes :

  • Personnaliser le déplacement et redimensionner des glyphes avec des graphiques améliorés.

  • Ajouter un glyphe à l'aire de conception qui incline le contrôle sélectionné lors du déplacement de la souris.

  • Modifier l'apparence et le comportement d'un contrôle au moment du design pour différents outils.

L'architecture Concepteur WPF prend en charge la pleine puissance d'expression de WPF. Cela permet la création de nombreuses expériences utilisateur de conception visuelles, ce qui n'était pas possible précédemment.

Modèle objet du Concepteur WPF

Le modèle objet du Concepteur WPF est modulaire, ce qui signifie que lorsque vous étendez les fonctionnalités au moment du design, vous étendez uniquement les éléments nécessaires à vos fonctionnalités. Vous n'avez pas à écrire beaucoup de code pour mettre en œuvre vos fonctionnalités de design personnalisées. 

Le modèle objet se compose de cinq unités fonctionnelles, décrites dans le tableau suivant.

Unité fonctionnelle

Description

Modèle d'édition

Interface de programmation pour les objets dans le concepteur.

Fournisseurs de fonctionnalités

Point d'extensibilité principal dans l'infrastructure du concepteur.

Contexte d'édition

Magasin central pour l'état d'un concepteur.

Outils

Outils pour traiter l'entrée d'utilisateur.

Magasin de métadonnées

Magasin qui contient le comportement au moment du design d'un contrôle afin de séparer physiquement la logique concepteur de la logique d'exécution.

L'illustration suivante montre le modèle objet du Concepteur WPF.

Modèle d'objet de niveau supérieur

Remarque :

Le Concepteur WPF prend en charge l'infrastructure d'extensibilité totale. Expression Blend ne prend en charge que les éditeurs de propriétés, le chargement de métadonnées et la gestion des licences. Cette application ne prend pas en charge les actions de menu ni les ornements. 

Modèle d'édition

L'environnement de conception interagit avec les contrôles au moment de l'exécution via une interface de programmation appelée un modèle d'édition. The editing model consists of three functional subunits: a model, a public wrapper that abstracts the model, and a view that represents the user interface (UI) of the model.

L'environnement de conception utilise le type ModelItem pour communiquer avec le modèle sous-jacent. Toutes les modifications sont apportées aux wrappers ModelItem, qui affectent le modèle sous-jacent. Cela permet au modèle d'être simple. Les wrappers ModelItem gèrent des fonctionnalités concepteur complexes telles que la prise en charge des transactions, le suivi des annulations et les notifications de modification.

La classe ModelService fournit le point d'entrée pour le modèle d'édition et pour les notifications d'événements globaux.

La classe ViewService mappe les représentations visuelles aux éléments de modèle sous-jacents.

Les deux services sont requis pour que le concepteur fonctionne. La classe DesignerView, qui est chargée de traiter l'entrée d'utilisateur et de la router vers les commandes, requiert ces deux services pour mapper correctement l'entrée d'utilisateur au modèle.

Fournisseurs de fonctionnalités

Vous étendez le comportement au moment du design de vos types en utilisant les classes FeatureProvider ou FeatureConnector<FeatureProviderType>. La classe FeatureConnector<FeatureProviderType> gère une liste d'objets FeatureProvider.

La classe FeatureProvider fournit le point d'extensibilité le plus basique. Un fournisseur de fonctionnalités est une fonctionnalité ou un complément léger qui ne requiert en général pas beaucoup de l'environnement de conception et est créé et détruit dans un contexte donné. Les fournisseurs de fonctionnalités sont utilisés pour ajouter de nouveaux éléments d'interface utilisateur à l'aire de conception ou pour modifier un comportement de base. Par exemple, un fournisseur de fonctionnalités peut ajouter plus de poignées de manipulation ou permettre un nouveau type de comportement de glissement de souris.

Pour accéder au niveau le plus élevé d'extensibilité, dérivez de la classe FeatureConnector<FeatureProviderType>. Cette classe expose un fournisseur de services, par lequel les classes connecteur de fonctionnalités dérivées peuvent gérer des événements et des requêtes ainsi que publier des services. Par exemple, vous pouvez implémenter un connecteur de fonctionnalités pour fournir une interface utilisateur de sélection ou une sérialisation spécifique à l'objet.

En général, implémentez une fonctionnalité pour étendre des concepts existants. Implémentez un connecteur de fonctionnalités pour fournir de nouveaux concepts. For more information, see Fournisseurs de fonctionnalités et connecteurs de fonctionnalités.

Editing Context

Une quantité significative d'informations d'état est accumulée dans un concepteur en cours d'exécution. Par exemple, l'état de votre concepteur peut comprendre : les objets actuellement sélectionnés ou le comportement lorsque le bouton gauche de la souris est enfoncé. L'état du concepteur est stocké en un emplacement central, afin de le trouver aisément. La classe EditingContext représente ce référentiel central des états du concepteur.

La classe EditingContext partage l'état en deux catégories : données et comportement. Les données sont stockées comme une table d'éléments de contexte et le comportement est stocké comme une table de services. Les deux tables sont indexées par une clé basée sur un type et sont dénombrables.

La classe ContextItem conserve une information d'état unique dans le concepteur. Les éléments de contexte sont immuables, mais de nouveaux éléments de contexte peuvent remplacer les éléments existants pour simuler la mutabilité.

On accède aux services via une propriété Services, qui retourne une instance de ServiceManager, et on accède aux éléments de contexte via une propriété Items, qui retourne une instance de ContextItemManager.

Commandes, tâches et outils

L'architecture des outils du Concepteur WPF se compose des commandes, des tâches et des outils. 

Une commande est un identificateur unique correspondant à un certain comportement. Par exemple, « Couper » est une commande qui destine à couper le texte actuel et l'ajouter au Presse-papiers. Le code qui implémente « Couper » varie d'une application à l'autre, et peut même varier au sein d'une même application. Par exemple, la fonction Couper du texte dans un document Word possède une implémentation différente de la fonction Couper du texte dans la zone de texte Rechercher du même document. Indépendamment de l'implémentation, la commande « Couper » reste constante.

Le Concepteur WPF accroît le système de commandes WPF en introduisant le concept de commande d'outil. Une commande d'outil implémente l'interface ICommand et est similaire à la classe RoutedCommand.

Une tâche possède une collection de liaisons de commande, qui vous permet d'ajouter des commandes routées. La classe DesignerView détient le code qui utilise la même stratégie de routage que les commandes d'outils pour rechercher et exécuter des commandes routées définies sur les tâches. La classe DesignerView active des tâches qui prennent en charge les commandes WPF courantes, telles que Copy.

Un outil est une classe qui traite l'entrée d'utilisateur. Toute entrée d'utilisateur produit dans le concepteur un ou plusieurs événements d'entrée. Ces événements d'entrée sont passés à l'outil actuellement actif qui les convertit en liaisons d'entrée. Si une liaison d'entrée est retournée, la commande de la liaison est exécutée.

Un outil peut représenter le mode global du concepteur. Par exemple, si l'utilisateur sélectionne des composants sur l'aire de conception, ce mode de sélection est possible parce que l'outil actuellement actif offre des liaisons d'entrée et commande cette sélection de handle. Lorsque l'utilisateur crée une nouvelle instance d'un contrôle, un autre outil devient actif et offre un ensemble différent de commandes, liées aux mêmes liaisons d'entrée.

Metadata Store

Dans l'infrastructure du Concepteur WPF, les métadonnées qui définissent le comportement au moment du design d'un contrôle sont stockées dans un assembly séparé, appelé le magasin de métadonnées. Dans .NET Framework 3.5, le magasin de métadonnées est implémenté dans des tables d'attributs basées sur du code, avec un fichier XML externe qui fait référence au code et au profil concepteur. Des outils différents peuvent fournir des magasins de métadonnées différents avec des implémentations de concepteur complètement différentes. Cela dissocie le comportement au moment de l'exécution et au moment du design, afin que vous puissiez modifier séparément le concepteur du contrôle. For more information, see Magasin de métadonnées.

Création de l'instance de concepteur

Les étapes suivantes indiquent comment un type concepteur d'exemple peut être instancié par l'environnement du Concepteur WPF. Cet exemple illustre la manière dont un concepteur hypothétique peut sélectionner un contrôle bouton unique sur l'aire de conception.

  1. L'utilisateur appelle une action définie par l'outil qui demande la création d'un concepteur personnalisé.

  2. L'environnement de conception énumère une liste en XML d'associations fonctionnalité-type.

  3. L'environnement de conception ajoute des métadonnées personnalisées à ces types en utilisant la classe TypeDescriptor. Par exemple, un GrabHandleProvider pourrait être associé à tous les types UIElement, y compris les types dérivés.

  4. Une fabrique d'éditions crée un magasin d'éditions, un contexte et un gestionnaire de fonctionnalités et remplit le magasin d'éditions.

  5. Le Concepteur WPF énumère tous les objets UIElement qui sont exposés par le magasin d'éditions et appelle la méthode InitializeFeatures pour chacun de ces objets.

    1. Supposez qu'un élément Button est déclaré dans cette hiérarchie.

    2. FeatureManager recherche un FeatureAttribute sur le bouton. FeatureManager découvre un FeatureAttribute sur le bouton de type GrabHandleProvider.

    3. FeatureManager continue à rechercher le type GrabHandleProvider et découvre un FeatureConnectorAttribute lui étant associé. FeatureConnectorAttribute spécifie SelectionConnector.

    4. FeatureManager détermine que cet hôte n'existe pas encore. FeatureManager crée SelectionConnector et l'ajoute à la liste des hôtes de fonctionnalités actifs.

    5. L'objet SelectionConnector commence à surveiller l'aire de conception pour toute modification de sélection. L'objet SelectionConnector obtient également une référence à la couche d'ornements.

  6. L'utilisateur sélectionne le bouton et l'outil au moment du design déclenche un événement de modification de sélection.

  7. SelectionConnector reçoit cette notification et crée toutes les instances FeatureProvider, basées la sur sélection, associées à l'objet sélectionné, y compris l'instance GrabHandleProvider.

  8. SelectionConnector interroge GrabHandleProvider pour obtenir une liste d'ornements et les ajoute à la couche d'ornements. Les poignées de manipulation apparaissent autour du bouton sélectionné.

Assemblys du Concepteur WPF

Le Concepteur WPF se compose de plusieurs assemblys qui appartiennent à l'une des trois catégories : public, privé et spécifique à Visual Studio.

Les assemblys publics exposent des classes que vous pouvez utiliser pour ajouter de la logique au moment du design à vos contrôles.

Les assemblys privés et spécifiques à Visual Studio définissent l'ensemble de fonctionnalités du Concepteur WPF et ses interactions avec Visual Studio. Le tableau suivant indique la manière dont les fonctionnalités du Concepteur WPF sont déployées.

Assembly

API publique

Description

Microsoft.VisualStudio.Xaml.dll

No

Logique d'intégration du Kit de développement Visual Studio SDK

Microsoft.Windows.Design.Host.dll

Oui

API publique pour le concepteur hébergeur (spécifique à Visual Studio)

Microsoft.Windows.Design.Developer.dll

No

Implémentation du Concepteur WPF. Seule l'API publique est une table d'attributs.

Microsoft.Windows.Design.Core.dll

Oui

Offre une base pour tout concepteur à travers un service et une infrastructure d'intégration (backplane) de données, et la manipulation de métadonnées. C'est le seul assembly pris en charge par Expression Blend.

Microsoft.Windows.Design.Extensibility.dll

Oui

Fournit un modèle d'extensibilité via des attributs.

Microsoft.Windows.Design.Interaction.dll

Oui

Fournit une entrée d'utilisateur et des classes d'affichage.

Microsoft.Windows.Design.Markup.dll

Oui

Fournit des mécanismes de langage XAML et de modèle de document.

Remarque :

Les assemblys représentent des limites de fonctionnalités et non des limites d'espace de noms. Vous trouverez souvent des espaces de noms qui couvrent un seul assembly.

Architecture du Concepteur WPF et du Concepteur Windows Forms

L'architecture du Concepteur WPF est considérablement différente de l'architecture du Concepteur Windows Forms, caractérisée par l'interface IComponent et l'espace de noms System.ComponentModel. For more information, see Comparaison entre l'infrastructure du Concepteur Windows Forms et l'infrastructure du concepteur WPF

Voir aussi

Concepts

Fournisseurs de fonctionnalités et connecteurs de fonctionnalités

Autres ressources

Développement de contrôles Windows Forms au moment du design

Extensibilité du concepteur WPF