Personnalisation de la création et du mouvement des éléments
Vous pouvez autoriser un élément à faire glisser vers les autres, de la boîte à outils ou dans une opération de collage ou de mouvements. Vous pouvez disposer les éléments déplacés liés aux éléments cibles, à l'aide de les relations que vous spécifiez.
Une directive de fusion d'élément (EMD) spécifie ce qui se produit lorsqu'un élément de modèle est fusionné dans un autre élément de modèle. Cela se produit lorsque :
L'utilisateur fait glisser de la boîte à outils vers le diagramme ou une forme.
L'utilisateur crée un élément à l'aide d'un menu pour ajouter dans l'explorateur ou une forme de compartiment.
L'utilisateur déplace un élément d'un couloir à un autre.
L'utilisateur coller un élément.
Votre code de programme appelle la directive de fusion d'élément.
Bien que les opérations de création peuvent sembler différentes des opérations de copie, il fonctionne réellement de la même façon. Lorsqu'un élément est ajouté, par exemple de la boîte à outils, un prototype de ce dernier est répliquée. Le prototype est fusionné dans le modèle de la même façon que les éléments qui ont été copiés d'une autre partie du modèle.
La responsabilité d'un EMD est de décider comment un objet ou un groupe d'objets doit être fusionné dans un emplacement particulier dans le modèle. En particulier, il détermine les relations doivent être instanciées pour incorporer le groupe fusionné dans le modèle. Vous pouvez également le personnaliser pour définir les propriétés et pour créer des objets supplémentaires.
le rôle d'une directive de fusion d'élément
Un EMD est généré automatiquement lorsque vous définissez une relation d'incorporation. Cette valeur par défaut EMD crée une instance de la relation lorsque les utilisateurs ajoutent de nouvelles instances enfants au parent. Vous pouvez modifier ces EMDs par défaut, par exemple en ajoutant du code personnalisé.
Vous pouvez également ajouter votre propre EMDs dans la définition de langage spécifique à un domaine, pour permettre aux utilisateurs de faire glisser ou pour coller différentes combinaisons des classes fusionnées et les réception.
définir une directive de fusion d'élément
Vous pouvez ajouter des directives de fusion d'élément aux classes, aux relations de domaine, pour dessiner des formes, des connecteurs, et des diagrammes. Vous pouvez les ajouter ou trouver dans l'explorateur DÉSOLÉ sous la classe réceptrice de domaine. La classe réceptrice est la classe de domaine de l'élément qui se trouve déjà dans le modèle, et sur laquelle l'élément nouveau ou copié sera fusionné.
classe d'indexation est la classe de domaine d'éléments qui peuvent être fusionnés dans des membres de la classe réceptrice. Les instances des sous-classes de la classe d'indexation seront également fusionnées par cet EMD, à moins que vous s'applique aux sous-classes la valeur False.
Il existe deux genres de directive de fusion :
Une directive de processus de fusion spécifie les relations dans lesquels le nouvel élément doit être lié dans l'arborescence.
Une directive en avant de fusion redirige le nouvel élément à un autre élément de destination, en général un parent.
Vous pouvez ajouter du code personnalisé aux directives de fusion :
Définissez Le personnalisé en charge acceptent pour ajouter votre propre code pour déterminer si une instance particulière de l'élément d'indexation doit être fusionnés dans l'élément cible. Lorsque l'utilisateur fait glisser de la boîte à outils, le pointeur « non valide » indique si votre code empêché la fusion.
Par exemple, vous pourriez permettre la fusion uniquement lorsque l'élément de réception est dans un état particulier.
Définissez Fusion personnalisée d'utilisation à ajouter fournissent propre code pour définir les modifications apportées au modèle lorsque la fusion est exécutée.
Par exemple, vous pouvez définir des propriétés dans l'élément fusionné avec des données de son nouvel emplacement dans le modèle.
Notes
Si vous écrivez du code personnalisé de fusion, il affecte uniquement les fusions qui sont exécutées à l'aide de cet EMD.S'il existe un autre EMDs qui fusionnent le même type d'objet, ou s'il existe un autre code personnalisé qui crée ces objets sans utiliser les EMD, puis ils ne seront pas affectées par votre code personnalisé de fusion.
Si vous souhaitez vous assurer qu'un nouvel élément ou une nouvelle relation est toujours traité par votre code personnalisé, envisagez de définir AddRule sur la relation d'incorporation et DeleteRule sur la classe du domaine de l'élément.Pour plus d'informations, consultez Propagation de modifications dans le modèle par des règles.
exemple : définir un EMD sans code personnalisé
L'exemple suivant permet aux utilisateurs de créer un élément et un connecteur en même temps en faisant glisser de la boîte à outils sur une forme existante. L'exemple ajoute un EMD à la définition de langage spécifique à un domaine. Avant cette modification, les utilisateurs peuvent faire glisser les outils vers le diagramme, mais pas sur exister forment.
les utilisateurs peuvent également coller des éléments sur d'autres éléments.
Pour permettre aux utilisateurs de créer un élément et un connecteur en même temps
Créez un nouveau domaine (à l'aide de le modèle de solution de langage minimal .
Lorsque vous exécutez ce code DÉSOLÉ, il vous permet de créer des formes et des connecteurs entre les formes. vous ne pouvez pas faire glisser une nouvelle forme d' ExampleElement de la boîte à outils sur une forme existante.
Pour permettre aux utilisateurs de fusionner des éléments sur les formes d' ExampleElement , créez un nouvel EMD dans la classe de domaine d' ExampleElement :
Dans Explorateur DÉSOLÉ, développez classes de domaine. Cliquez avec le bouton droit sur ExampleElement puis cliquez sur ajoutez la nouvelle directive de fusion d'élément.
Assurez -vous que la fenêtre de Détails DÉSOLÉ est ouverte, afin que vous puissiez voir les détails du nouvel EMD. (Menu : Afficher, Autres fenêtres, Détails DÉSOLÉ.)
Définissez classe d'indexation dans la fenêtre de détails DÉSOLÉ, pour définir la classe d'éléments peuvent être fusionnée sur des objets d' ExampleElement .
Pour cet exemple, sélectionnez ExampleElements, afin que l'utilisateur puisse faire glisser des éléments sur les éléments existants.
Notez que la classe d'indexation devient le nom de l'EMD dans l'explorateur DÉSOLÉ.
sous fusion de processus en créant des liens, ajoutez deux chemins d'accès :
un chemin d'accès lie le nouvel élément au modèle parent. L'expression de chemin que vous devez écrire navigue de l'élément existant, le haut via la relation d'incorporer au modèle parent. Enfin, il spécifie le rôle dans le nouveau lien vers lequel le nouvel élément est assignée. Le chemin d'accès est le suivant :
ExampleModelHasElements.ExampleModel/!ExampleModel/.Elements
l'autre chemin d'accès lie le nouvel élément à l'élément existant. L'expression de chemin spécifie la relation de référence et le rôle sur lequel le nouvel élément est assignée. Ce chemin d'accès est le suivant :
ExampleElementReferencesTargets.Sources
Vous pouvez utiliser l'outil de navigation de tracé pour créer chaque chemin d'accès :
sous Gérez la fusion en créant des liens aux chemins d'accès, cliquez sur <add path> .
Cliquez sur la flèche de déroulement à droite de l'élément de liste. une arborescence apparaît.
Développez les nœuds dans l'arborescence pour former le chemin d'accès que vous souhaitez spécifier.
Testez du code DÉSOLÉ :
appuyez sur F5 pour régénérer et exécuter la solution.
Régénérer prendra plus longue à habituel parce que le code généré sera mis à jour les modèles de texte pour se conformer à la nouvelle définition de langage spécifique à un domaine.
Lorsque l'instance expérimentale de Visual Studio a démarré, ouvrez un fichier de modèle de votre DÉSOLÉ. Créez des éléments d'exemple.
glisser-déplacer de l'outil d' élément d'exemple sur une forme existante.
Une nouvelle forme s'affiche, et elle est liée à la forme existante avec un connecteur.
copiez une forme existante. sélectionnez une forme et un collage différents.
une copie de la première forme est créée. Il possède un nouveau nom et est lié à la deuxième forme avec un connecteur.
Notez les points suivants de cette procédure :
En créant des directives de fusion d'éléments, vous pouvez permettre à n'importe quelle classe d'élément pour recevoir un autre. L'EMD est créé dans la classe réceptrice de domaine, et la classe reçue de domaine est spécifiée dans le champ d' Indexer la classe .
En définissant des chemins d'accès, vous pouvez spécifier ce qui lie doit être utilisé pour connecter le nouvel élément au modèle existant.
Les liens que vous spécifiez doit inclure une relation incorporante.
L'EMD affecte la conception de la boîte à outils et également les opérations de copier-coller.
Si vous écrivez du code personnalisé qui crée de nouveaux éléments, vous pouvez appeler explicitement un EMD à l'aide de la méthode d' ElementOperations.Merge . Cela permet de garantir que votre code contient des éléments dans le modèle de la même manière que les autres opérations. Pour plus d'informations, consultez Personnalisation du comportement de la commande copier.
exemple : Le personnalisé d'addition acceptent code à un EMD
En ajoutant du code personnalisé à un EMD, vous pouvez définir un comportement plus complexe de fusion. Cet exemple simple empêché l'utilisateur d'ajouter plus qu'un nombre fixe d'éléments vers le diagramme. l'exemple modifie la valeur par défaut EMD qui accompagne une relation d'incorporation.
Pour écrire le personnalisé acceptez code pour restreindre que l'utilisateur peut ajouter
Créez un DÉSOLÉ à l'aide de le modèle de solution de langage minimal . Ouvrez le schéma de définition de langage spécifique à un domaine.
Dans l'explorateur DÉSOLÉ, développez classes de domaine, ExampleModel, directives de fusion d'élément. sélectionnez la directive de fusion d'élément qui est nommée ExampleElement.
contrôles de cet EMD comment l'utilisateur peut créer de nouveaux objets d' ExampleElement dans le modèle, par exemple en faisant glisser de la boîte à outils.
dans la fenêtre de Détails DÉSOLÉ , sélectionnez Le personnalisé en charge acceptent.
Régénérez la solution. Cela prendra plus longue à habituel parce que le code généré sera mis à jour du modèle.
Une erreur de build sera enregistrée, semblable à la suivante : « Company.ElementMergeSample.ExampleElement ne contient pas de définition pour CanMergeExampleElement… »
Vous devez implémenter la méthode CanMergeExampleElement.
Créez un fichier de code du projet de DÉSOLÉ . Remplacez son contenu par le code suivant et modifiez l'espace de noms à l'espace de noms de votre projet.
using Microsoft.VisualStudio.Modeling; namespace Company.ElementMergeSample // EDIT. { partial class ExampleModel { /// <summary> /// Called whenever an ExampleElement is to be merged into this ExampleModel. /// This happens when the user pastes an ExampleElement /// or drags from the toolbox. /// Determines whether the merge is allowed. /// </summary> /// <param name="rootElement">The root element in the merging EGP.</param> /// <param name="elementGroupPrototype">The EGP that the user wants to merge.</param> /// <returns>True if the merge is allowed</returns> private bool CanMergeExampleElement(ProtoElementBase rootElement, ElementGroupPrototype elementGroupPrototype) { // Allow no more than 4 elements to be added: return this.Elements.Count < 4; } } }
cet exemple simple restreint le nombre d'éléments qui peuvent être fusionnés dans le modèle de parent. Pour les conditions plus intéressantes, la méthode peut vérifier les propriétés et les liens de l'de l'objet de réception. Elle peut également examiner les propriétés des éléments fusionnants, qui sont distribués dans ElementGroupPrototype. Pour plus d'informations sur ElementGroupPrototypes, consultez Personnalisation du comportement de la commande copier. Pour plus d'informations sur l'écriture de code qui lit un modèle, consultez Navigation et mise à jour d'un modèle dans le code de programme.
Testez du code DÉSOLÉ :
appuyez sur F5 pour régénérer la solution. Lorsque l'instance expérimentale de Visual Studio s'ouvre, ouvrez une instance de votre DÉSOLÉ.
Créez de nouveaux éléments de plusieurs façons :
glisser-déplacer de l'outil d' élément d'exemple sur le diagramme.
Dans Explorateur de modèles d'exemple, cliquez avec le bouton droit sur le nœud racine puis cliquez sur Ajouter un nouvel élément d'exemple.
copiez et collez un élément sur le diagramme.
Vérifiez que vous ne pouvez pas utiliser l'un de ces façons d'ajouter plus de quatre éléments au modèle. Cela est dû au fait qu'ils toute l'utilisation la directive de fusion d'élément.
exemple : Le code personnalisé de fusion à un EMD
Dans le code personnalisé de fusion, vous pouvez définir ce qui se produit lorsque l'utilisateur fait glisser un outil ou coller sur un élément. Il existe deux façons de définir une fusion personnalisée :
Définissez Fusion personnalisée d'utilisation et fournissez le code requis. Votre code remplace le code généré de fusion. utilisez cette option si vous souhaitez redéfinir complètement ce que la fusion fait.
substituez la méthode d' MergeRelate , et éventuellement la méthode d' MergeDisconnect . Pour ce faire, vous devez définir la propriété de génère double dérivé de la classe de domaine. Votre code peut appeler le code généré de fusion dans la classe de base. Utilisez cette option si vous voulez exécuter des opérations supplémentaires après la fusion a été exécutée.
Ces fusions d'impact d'autres uniquement exécutées à l'aide de cet EMD. Si vous souhaitez définir toutes les manières de l'élément fusionné peut être créé, vous pouvez également définir AddRule sur la relation d'incorporation et DeleteRule sur la classe fusionnée de domaine. Pour plus d'informations, consultez Propagation de modifications dans le modèle par des règles.
pour substituer MergeRelate
Dans la définition DÉSOLÉ, assurez -vous que l'EMD auquel vous souhaitez ajouter le code. Si vous le souhaitez, vous pouvez ajouter des chemins d'accès et définir le personnalisé acceptez le code comme décrit dans les sections précédentes.
Dans le diagramme de DslDefinition, sélectionnez la classe réceptrice de la fusion. Il s'agit en général d'une classe à l'extrémité source d'une relation d'incorporation.
Par exemple, dans un domaine (généré de la solution minimale de langage, sélectionnez ExampleModel.
dans la fenêtre de Propriétés , définissez génère double dérivé à true.
Régénérez la solution.
inspectez le contenu d' Dsl\Generated Files\DomainClasses.cs. Rechercher des méthodes nommées MergeRelate et examiner leur contenu. Cela vous permet d'écrire vos propres versions.
Dans un nouveau fichier de code, écrivez une classe partielle pour la classe réceptrice, et substituez la méthode d' MergeRelate . N'oubliez pas d'appeler la méthode de base. Par exemple :
partial class ExampleModel { /// <summary> /// Called when the user drags or pastes an ExampleElement onto the diagram. /// Sets the time of day as the name. /// </summary> /// <param name="sourceElement">Element to be added</param> /// <param name="elementGroup">Elements to be merged</param> protected override void MergeRelate(ModelElement sourceElement, ElementGroup elementGroup) { // Connect the element according to the EMD: base.MergeRelate(sourceElement, elementGroup); // Custom actions: ExampleElement mergingElement = sourceElement as ExampleElement; if (mergingElement != null) { mergingElement.Name = DateTime.Now.ToLongTimeString(); } } }
Pour écrire du code personnalisé de fusion
Dans Dsl\Generated Code\DomainClasses.cs, analysez les méthodes nommées MergeRelate. Ces méthodes créent des liens entre un élément et le modèle existant.
En outre, analysez les méthodes nommées MergeDisconnect. Ces méthodes dissocier un élément du modèle lorsqu'il doit être supprimé.
dans Explorateur DÉSOLÉ, sélectionnez ou créez la directive de fusion d'élément que vous souhaitez personnaliser. dans la fenêtre de Détails DÉSOLÉ , définissez Fusion personnalisée d'utilisation.
Lorsque vous définissez cette option, les options de Gérez la fusion et de Transférer la fusion avez ignoré. votre code est utilisé à la place.
Régénérez la solution. Il prendra plus longue à habituel parce que les fichiers de code générés sont mis à jour du modèle.
Les messages d'erreur s'afficheront. Double-cliquez sur les messages d'erreur pour afficher l'instruction dans le code généré. Cette instruction vous demande de fournir deux méthodes, MergeRelateYourDomainClass et MergeDisconnectYourDomainClass
Écrivez les méthodes dans une définition de classe partielle dans un fichier de code distinct. Les exemples que vous avez effectuée précédemment doivent suggérer de vos besoins.
Le code personnalisé de fusion n'affecte pas le code qui crée des objets et des relations directement, et il n'affecte pas l'autre EMDs. Pour garantir que vos modifications supplémentaires sont implémentées indépendamment de la façon dont l'élément est créé, envisagez d'écrire AddRule et DeleteRule à la place. Pour plus d'informations, consultez Propagation de modifications dans le modèle par des règles.
rediriger une opération de fusion
une directive en avant de fusion redirige la cible d'une opération de fusion. en général, la nouvelle cible est le parent d'incorporation de la cible initiale.
Par exemple, dans un langage spécifique à un domaine qui a été créé avec le modèle de diagramme de composant, les ports sont incorporés dans les composants. Les ports sont affichés comme des petites formes au bord d'une forme de composant. L'utilisateur crée des ports en faisant glisser l'outil de port sur une forme de composant. Mais parfois, l'utilisateur fait glisser de par inadvertance l'outil de port sur un port existant, au lieu du composant et, l'opération échoue. Il s'agit d'une erreur facile lorsqu'il existe plusieurs ports existants. Pour aider l'utilisateur à éviter cette interfère avec, vous pouvez permettre aux ports à faire glisser sur un port existant, mais utilise l'action redirigée dans le composant parent. L'opération fonctionne comme si l'élément cible s'agissait du composant.
Vous pouvez créer une directive en avant de fusion dans la solution de modèle de composant. Si vous compilez et exécutez la solution d'origine, vous devez voir que les utilisateurs peuvent faire glisser un nombre quelconque d'éléments de port d'entrée ou de port de sortie de boîte à outils à un élément de Composant . Toutefois, ils ne peuvent pas faire glisser un port à un port existant. Le pointeur non disponible les alerte que ce transfert n'est pas activé. Toutefois, vous pouvez créer une directive en avant de fusion pour qu'un port qui est involontairement déplacé sur port d'entrée existant est transféré à l'élément de Composant .
pour créer une directive en avant de fusion
Créez une solution de Outils DSL (Domain-Specific Language) à l'aide de le modèle de modèle composant.
affichez Explorateur DÉSOLÉ en ouvrant DslDefinition.dsl.
Dans Explorateur DÉSOLÉ, développez classes de domaine.
La classe de domaine abstract ComponentPort est la classe de base d' InPort et d' OutPort. Cliquez avec le bouton droit sur ComponentPort puis cliquez sur ajoutez la nouvelle directive de fusion d'élément.
Un nouveau nœud de directive de fusion d'élément s'affiche sous le nœud de directives de fusion d'élément .
Sélectionnez le nœud de directive de fusion d'élément et ouvrez la fenêtre de Détails DÉSOLÉ .
dans la liste des élèves d'indexation, sélectionnez ComponentPort.
sélectionnez Faites suivre pour fusionner une classe différente de domaine.
Dans la liste de sélection de chemin d'accès, développez ComponentPort, développez ComponentHasPorts, puis sélectionnez Composant.
Le nouveau chemin d'accès doit ressembler à celui-ci :
ComponentHasPorts.Component/! composant
Enregistrez la solution, puis définissez les modèles en cliquant sur le bouton à droite de la barre d'outils d' Explorateur de solutions .
Générez et exécutez la solution. Une nouvelle instance de Visual Studio s'affiche.
dans Explorateur de solutions, ouvrez Sample.mydsl. le diagramme et le boîte à outils de ComponentLanguage apparaissent.
faites glisser port d'entrée de boîte à outils à un autre port d'entrée. Ensuite, faites glisser OutputPort à InputPort puis à un autre OutputPort.
Vous ne devez pas voir le pointeur non disponible, et vous devez peut-être supprimer nouveau port d'entrée sur existant. Sélectionnez nouveau port d'entrée et faites -le glisser vers un autre point sur Composant.
Voir aussi
Concepts
Navigation et mise à jour d'un modèle dans le code de programme
Personnalisation des outils et de la boîte à outils