Comment : ajouter une commande au menu contextuel
Vous pouvez ajouter des commandes de menu à votre langage (DSL) spécifique au domaine afin que vos utilisateurs puissent effectuer les tâches spécifiques à votre DÉSOLÉ.Les commandes apparaissent dans le menu de contexte (raccourci) lorsque les utilisateurs cliquent avec le bouton droit sur le diagramme.Vous pouvez définir une commande afin qu'il apparaisse uniquement dans le menu dans des circonstances spécifiques.Par exemple, vous pouvez rendre la commande visibles uniquement lorsque l'utilisateur clique sur des types spécifiques d'éléments, ou des éléments des rapports spécifiques.
En résumé, les étapes sont exécutées dans le projet de DslPackage, comme suit :
Déclarez l'ordre dans Commands.vsct
mettez à jour le numéro de version de package dans Package.tt.Vous devez effectuer cette opération chaque fois que vous modifiez Commands.vsct
Méthodes write dans la classe de CommandSet pour rendre la commande visible et pour définir ce que vous souhaitez que la commande à faire.
Pour obtenir des exemples, Visualization and Modeling SDK websiteconsultez.
[!REMARQUE]
Vous pouvez également modifier le comportement de certaines commandes existantes telles que couper, coller, sélectionner tous, et la copie par la substitution de méthodes dans CommandSet.cs.Pour plus d'informations, consultez Comment : modifier une commande de menu standard dans un langage spécifique à un domaine.
Définition d'une commande à l'aide de MEF
L' (MEF)managed extension fournit une autre méthode de définir des commandes de menu dans le menu de diagramme.Son objectif principal consiste à activer un DÉSOLÉ à étendre par vous-même ou d'autres parties.Les utilisateurs peuvent choisir d'installer simplement le DÉSOLÉ, ou peuvent installer le langage DÉSOLÉ et des extensions.Toutefois, MEF réduit également le travail de définir des commandes de menu contextuel, après le travail initial d'activer MEF sur le langage spécifique à un domaine.
Utilisez la méthode de cette rubrique si :
Vous souhaitez définir des commandes de menu dans les menus autres que le menu contextuel de bouton droit.
Vous souhaitez définir des regroupements spécifiques des commandes dans le menu.
Vous ne souhaitez pas permettre à d'autres d'étendre le code DÉSOLÉ avec leurs propres commandes.
Vous souhaitez uniquement définir une commande.
Sinon, utilisez la méthode MEF pour définir des commandes.Pour plus d'informations, consultez Extension de votre DSL à l'aide de MEF.
Déclarez l'ordre dans Commands.Vsct
Les commandes de menu sont déclarées dans DslPackage \Commands .vsct.Ces définitions spécifient les noms d'éléments de menu et où elles apparaissent dans les menus.
Le fichier que vous la modification, Commands.vsct, importe des définitions à partir de plusieurs fichiers .h, situés dans le répertoire Le kit de développement Visual Studio chemin d'installation\VisualStudioIntegration\Common\Inc.Elle inclut également GeneratedVsct.vsct, généré à partir de votre définition de langage spécifique à un domaine.
Pour plus d'informations sur les fichiers de .vsct, consultez Tableau de commande Visual Studio (. fichiers de Vsct).
pour ajouter la commande
dans Explorateur de solutions, sous le projet de DslPackage , ouvrez Commands.vsct.
dans l'élément d' Commands , définissez un ou plusieurs boutons et un groupe.Un bouton est un élément dans le menu.un groupe est une section dans le menu.pour définir ces éléments, ajoutez les éléments suivants :
<!-- Define a group - a section in the menu --> <Groups> <Group guid="guidCustomMenuCmdSet" id="grpidMyMenuGroup" priority="0x0100"> <!-- These symbols are defined in GeneratedVSCT.vsct --> <Parent guid="guidCmdSet" id="menuidContext" /> </Group> </Groups> <!-- Define a button - a menu item - inside the Group --> <Buttons> <Button guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand" priority="0x0100" type="Button"> <Parent guid="guidCustomMenuCmdSet" id="grpidMyMenuGroup"/> <!-- If you do not want to place the command in your own Group, use Parent guid="guidCmdSet" id="grpidContextMain". These symbols are defined in GeneratedVSCT.vsct --> <CommandFlag>DynamicVisibility</CommandFlag> <Strings> <ButtonText>My Context Menu Command</ButtonText> </Strings> </Button> </Buttons>
[!REMARQUE]
Chaque bouton ou groupe est identifié par le GUID et un ID d'entiersVous pouvez créer plusieurs groupes et boutons avec le même GUID.Toutefois, elles doivent avoir des identificateurs.Les noms de GUID et les noms d'ID sont traduits à GUID réelle et à identificateurs numériques dans le nœud de <Symbols> .
Ajoutez une contrainte de visibilité pour la commande afin d'être chargé uniquement dans le contexte de votre langage spécifique au domaine.Pour plus d'informations, consultez VisibilityConstraints, élément.
Pour cela, ajoutez les éléments suivants dans l'élément d' CommandTable après l'élément d' Commands .
<VisibilityConstraints> <!-- Ensures the command is only loaded for this DSL --> <VisibilityItem guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand" context="guidEditor"/> </VisibilityConstraints>
Définissez des noms que vous avez utilisés pour les GUID et les identificateurs.Pour cela, ajoutez un élément de Symbols dans l'élément d' CommandTable après l'élément d' Commands .
<Symbols> <!-- Substitute a unique GUID for the placeholder: --> <GuidSymbol name="guidCustomMenuCmdSet" value="{00000000-0000-0000-0000-000000000000}" > <IDSymbol name="grpidMyMenuGroup" value="0x01001"/> <IDSymbol name="cmdidMyContextMenuCommand" value="0x00001"/> </GuidSymbol> </Symbols>
Remplacez {000...000} par le GUID identifiant vos groupes et éléments de menu.Pour obtenir un nouveau GUID, utilisez l'outil de Create GUID dans le menu d' Outils .
[!REMARQUE]
Si vous ajoutez plus de groupes ou d'éléments de menu, vous pouvez utiliser le même GUID.Toutefois, vous devez utiliser de nouvelles valeurs pour IDSymbols.
Dans le code que vous avez copié à partir de cette procédure, remplacez chaque occurrence des chaînes suivantes par vos propres chaînes :
grpidMyMenuGroup
cmdidMyContextMenuCommand
guidCustomMenuCmdSet
ma commande de menu contextuel
Mettez à jour la version du package dans Package.tt
Chaque fois que vous ajoutez ou modifiez une commande, mettez à jour le paramètre d' version d' ProvideMenuResourceAttribute qui est appliqué à la classe du package avant de diffuser la nouvelle version de votre langage spécifique au domaine.
Étant donné que la classe du package est définie dans un fichier généré, mettez à jour l'attribut dans le fichier de modèle de texte qui génère le fichier de Package.cs.
Pour mettre à jour le fichier de Package.tt
dans Explorateur de solutions, dans le projet de DslPackage , dans le dossier de GeneratedCode , ouvrez le fichier de Package.tt.
Recherchez l'attribut d' ProvideMenuResource .
incrémentez le paramètre d' version de l'attribut, qui est le deuxième paramètre.Si vous le souhaitez, vous pouvez entrer le nom de paramètre explicite pour vous rappelle de son objectif.Par exemple :
[VSShell::ProvideMenuResource("1000.ctmenu", version: 2 )]
définissez le comportement de la commande
Votre DÉSOLÉ est déjà des commandes qui sont implémentées dans une classe partielle qui est déclarée dans DslPackage \GeneratedCode\CommandSet .cs.pour ajouter de nouvelles commandes, vous devez étendre cette classe en créant un nouveau fichier qui contient une déclaration partielle de la même classe.Le nom de la classe est généralement <YourDslName> CommandSet.Il est utile de démarrer en vérifiant le nom de la classe et en consultant son contenu.
la classe de jeu de commandes est dérivée d' CommandSet.
pour étendre la classe de CommandSet
Dans l'explorateur de solutions, dans le projet de DslPackage, ouvrez le dossier GeneratedCode puis le regardez sous CommandSet.tt et ouvrez le fichier généré CommandSet.cs.Notez l'espace de noms et le nom de la première classe définie à cet endroit.Par exemple, vous pouvez voir :
namespace Company.Language1
{ ... internal partial class Language1CommandSet : ...
Dans DslPackage, créez un dossier nommé custom code.Dans ce dossier, créez un nouveau fichier de classe appelé CommandSet.cs.
Dans le nouveau fichier, écrivez une déclaration partielle qui a le même espace de noms et nom que la classe partielle générée.Par exemple :
namespace Company.Language1 /* Make sure this is correct */
{ internal partial class Language1CommandSet { ...
Remarque si vous avez utilisé le modèle de classe pour créer le nouveau fichier, vous devez corriger l'espace de noms et le nom de la classe.
étendez la classe de jeu de commandes
Votre code de jeu de commandes doit généralement importer les espaces de noms suivants :
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Shell;
Modifiez l'espace de noms et le nom de la classe pour correspondre à celles du CommandSet.cs généré :
namespace Company.Language1 /* Make sure this is correct */
{
// Same class as the generated class.
internal partial class Language1CommandSet
{
Vous devez définir deux méthodes, une pour déterminer quand la commande n'est visible dans le menu contextuel, et l'autre pour exécuter la commande.ces méthodes ne sont pas des substitutions ; à la place, vous les enregistrez dans une liste de commandes.
Définissez lorsque la commande est visible
Pour chaque commande, définissez une méthode d' OnStatus... qui détermine si la commande apparaîtra dans le menu, et si elle est activée ou greyed.Définissez les propriétés d' Visible et d' Enabled d' MenuCommand, comme indiqué dans l'exemple suivant.Cette méthode est appelée pour construire le menu contextuel lorsque l'utilisateur clique avec le bouton droit sur le diagramme, il doit fonctionner rapidement.
Dans cet exemple, la commande est visible uniquement lorsque l'utilisateur a sélectionné un type particulier de forme, et est disponible uniquement lorsqu'au moins un des éléments sélectionnés est dans un état particulier.L'exemple est basé sur le modèle du diagramme de classes DÉSOLÉ, et ClassShape et ModelClass sont des types définis dans du code DÉSOLÉ :
private void OnStatusMyContextMenuCommand(object sender, EventArgs e)
{
MenuCommand command = sender as MenuCommand;
command.Visible = command.Enabled = false;
foreach (object selectedObject in this.CurrentSelection)
{
ClassShape shape = selectedObject as ClassShape;
if (shape != null)
{
// Visibility depends on what is selected.
command.Visible = true;
ModelClass element = shape.ModelElement as ModelClass;
// Enabled depends on state of selection.
if (element != null && element.Comments.Count == 0)
{
command.Enabled = true;
return; // seen enough
} } } }
Les fragments suivants sont souvent utiles dans les méthodes d'OnStatus :
this.CurrentSelection.La forme que l'utilisateur a un clic avec le bouton droit est toujours inclus dans cette liste.Si l'utilisateur clique sur une partie vide du diagramme, le diagramme est le seul membre de la liste.
this.IsDiagramSelected() - true si l'utilisateur a cliqué sur une partie vide du diagramme.
this.IsCurrentDiagramEmpty()
this.IsSingleSelection() - l'utilisateur n'a pas sélectionné plusieurs objets
this.SingleSelection - la forme ou diagramme que l'utilisateur a sélectionnés avec le bouton droit sur
shape.ModelElement as MyLanguageElement - l'élément de modèle représenté par une forme.
En règle générale, définissez la propriété d' Visible dépendre sur ce qui est sélectionnée, et la propriété d' Enabled dépendre de l'état des éléments sélectionnés.
Une méthode d'OnStatus ne doit pas modifier l'état du magasin.
Définissez ce que la commande oblige
Pour chaque commande, définissez une méthode d' OnMenu... qui exécute les actions nécessaires lorsque l'utilisateur clique sur la commande de menu.
Si vous apportez des modifications aux éléments de modèle, vous devez le faire dans une transaction.Pour plus d'informations, consultez Comment : modifier une commande de menu standard dans un langage spécifique à un domaine.
Dans cet exemple, ClassShape, ModelClass, et Comment sont des types définis dans du code DÉSOLÉ, qui est dérivé du modèle du diagramme de classes DÉSOLÉ.
private void OnMenuMyContextMenuCommand(object sender, EventArgs e)
{
MenuCommand command = sender as MenuCommand;
Store store = this.CurrentDocData.Store;
// Changes to elements and shapes must be performed in a Transaction.
using (Transaction transaction =
store.TransactionManager.BeginTransaction("My command"))
{
foreach (object selectedObject in this.CurrentSelection)
{
// ClassShape is defined in my DSL.
ClassShape shape = selectedObject as ClassShape;
if (shape != null)
{
// ModelClass is defined in my DSL.
ModelClass element = shape.ModelElement as ModelClass;
if (element != null)
{
// Do required action here - for example:
// Create a new element. Comment is defined in my DSL.
Comment newComment = new Comment(element.Partition);
// Every element must be the target of an embedding link.
element.ModelRoot.Comments.Add(newComment);
// Set properties of new element.
newComment.Text = "This is a comment";
// Create a reference link to existing object.
element.Comments.Add(newComment);
}
}
}
transaction.Commit(); // Don't forget this!
}
}
Pour plus d'informations sur la navigation de l'objet à l'objet dans le modèle, et sur la façon de créer des objets et des liens, consultez Comment : modifier une commande de menu standard dans un langage spécifique à un domaine.
enregistrez la commande
Répétez en c# les déclarations de GUID et des valeurs d'ID que vous avez effectuées dans la section de symboles de CommandSet.vsct :
private Guid guidCustomMenuCmdSet =
new Guid("00000000-0000-0000-0000-000000000000");
private const int grpidMyMenuGroup = 0x01001;
private const int cmdidMyContextMenuCommand = 1;
Utilisez la même valeur GUID que vous avez inséré dans Commands.vsct.
[!REMARQUE]
Si vous modifiez la section de symboles du fichier de VSCT, vous devez également modifier ces déclarations correspondent.Vous devez aussi incrémenter le numéro de version dans Package.tt
Enregistrez vos commandes de menu dans le cadre de ce jeu de commandes.GetMenuCommands() est appelé une fois lorsque le diagramme est initialisé :
protected override IList<MenuCommand> GetMenuCommands()
{
// Get the list of generated commands.
IList<MenuCommand> commands = base.GetMenuCommands();
// Add a custom command:
DynamicStatusMenuCommand myContextMenuCommand =
new DynamicStatusMenuCommand(
new EventHandler(OnStatusMyContextMenuCommand),
new EventHandler(OnMenuMyContextMenuCommand),
new CommandID(guidCustomMenuCmdSet, cmdidMyContextMenuCommand));
commands.Add(myContextMenuCommand);
// Add more commands here.
return commands;
}
testez la commande
Générez et exécutez le code DÉSOLÉ dans une instance expérimentale de Visual Studio.La commande doit s'afficher dans le menu contextuel dans les situations que vous avez spécifiées.
Pour tester la commande
Dans la barre d'outils Explorateur de solutions , cliquez sur Transformer tous les modèles.
Appuyez sur F5 pour régénérer la solution, puis commencez à déboguer le langage spécifique au domaine dans la génération expérimentale.
Dans la génération expérimentale, ouvrez un diagramme d'exemple.
Cliquez avec le bouton droit sur les différents éléments dans le diagramme pour vérifier que la commande est correctement activée ou désactivée, et correctement affiché ou masqué, selon l'élément sélectionné.
Dépannage
La commande ne s'affiche pas dans le menu :
La commande apparaîtra uniquement dans des instances de débogage de Visual Studio, jusqu'à ce que vous avez installé le package DÉSOLÉ.Pour plus d'informations, consultez Déploiement de solutions de langage spécifique à un domaine.
Assurez -vous que votre exemple expérimental porte l'extension de nom de fichier appropriée pour ce langage spécifique à un domaine.pour activer l'extension de nom de fichier, ouvrez DslDefinition.dsl dans l'instance principale de Visual Studio.Ensuite dans l'explorateur DÉSOLÉ, cliquez avec le bouton droit sur le nœud de l'éditeur, puis cliquez sur propriétés.dans la fenêtre Propriétés, examinez la propriété de FileExtension.
Si vous incrémentez le numéro de version de package?
définissez un point d'arrêt au début de votre méthode d'OnStatus.Il doit arrêter lorsque vous cliquez avec le bouton droit sur toute partie du diagramme.
la méthode d'OnStatus n'est pas appelée:
Assurez -vous que les GUID et des identificateurs dans votre code de CommandSet correspondent à ceux de la section de symboles de Commands.vsct.
Dans Commands.vsct, assurez -vous que le GUID et l'ID dans chaque nœud parent identifient le groupe parent correct.
dans une invite de commandes de Visual Studio, tapez le devenv /rootsuffix exp /setup.Redémarrez l'instance de débogage de Visual Studio.
Parcourez la méthode d'OnStatus pour vérifier cette commande. visible et commande. Actif sont définis valeur true.
Le texte incorrecte de menu apparaît, ou la commande apparaît dans le mauvais:
Assurez -vous que la combinaison de GUID et de l'ID est unique à cette commande.
assurez-vous que vous avez désinstallé des versions antérieures du package.
Voir aussi
Concepts
Comment : modifier une commande de menu standard dans un langage spécifique à un domaine
Autres ressources
Écriture de code pour personnaliser un langage spécifique à un domaine