Ajouter des commandes Visual Studio

Une commande représentée par la Command classe est une action qui peut être lancée par un utilisateur, par exemple lorsque l’utilisateur choisit un élément de menu, appuie sur un bouton de barre d’outils ou tape un raccourci clavier. Les commandes ont un nom complet, une méthode d’exécution (ExecuteCommandAsync) qui effectue l’action, une icône d’affichage dans la barre d’outils pour identifier la commande et une info-bulle pour expliquer la commande à l’utilisateur. Les commandes peuvent être activées ou désactivées en fonction de différentes conditions.

Les commandes du nouveau modèle d’extensibilité s’exécutent de manière asynchrone afin que l’utilisateur puisse continuer à interagir avec l’IDE pendant l’exécution des commandes.

Utiliser des commandes

Cette vue d’ensemble couvre ces principaux scénarios d’utilisation des commandes :

Créer une commande

La création d’une commande avec le nouveau modèle d’extensibilité commence par l’extension de la classe Commandde base, l’ornement de la classe avec l’attribut et l’implémentation VisualStudioContribution de la CommandConfiguration propriété.

[VisualStudioContribution]
public class MyCommand : Command
{
  /// <inheritdoc />
  public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%");
}

Classe CommandConfiguration

La CommandConfiguration classe a quelques paramètres que vous devez connaître :

Paramètre Type Requise Description
DisplayName Chaîne Oui Nom d’affichage par défaut de votre commande. Entourez cette chaîne avec le caractère « % » pour permettre la localisation de cette chaîne. Voir à l’adresse Localiser les métadonnées.
ToolTipText Chaîne Non Texte à afficher en tant qu’info-bulle lorsque la commande est pointée ou prioritaire. Entourez cette chaîne avec le caractère « % » pour permettre la localisation de cette chaîne. Voir à l’adresse Localiser les métadonnées
Indicateurs CommandFlags Non Indicateurs pour définir des propriétés supplémentaires sur la commande. Certaines options incluent CanToggle et CanSelect. Consultez les indicateurs de commande.
Dispositions CommandPlacement[] Non Spécifie les groupes existants dans Visual Studio auxquels la commande sera parentée. Voir à l’adresse Placer une commande dans l’IDE. Même sans placement, votre commande sera toujours disponible via la fonctionnalité De recherche Visual Studio. Les commandes peuvent également être placées dans les menus, les barres d’outils et les groupes définis dans votre extension.
Icône CommandIconConfiguration Non Les commandes peuvent être affichées dans l’interface utilisateur sous la forme d’une icône, d’une icône avec du texte ou simplement d’un texte. Cette propriété configure ce que doit être cette icône, le cas échéant, et la façon dont elle doit être affichée.
Raccourcis CommandShortcutConfiguration[] Non Définit l’ensemble de combinaisons de touches qui peuvent être utilisées pour exécuter la commande. Les raccourcis peuvent être limités pour être applicables uniquement aux contextes d’IDE spécifiques. Voir les raccourcis.
ClientContexts[] Chaîne Non Contextes client demandés par la commande. Par défaut, les contextes Shell et Éditeur sont retournés. Un contexte client est un instantané d’états IDE spécifiques au moment où une commande a été exécutée à l’origine. Étant donné que ces commandes sont exécutées de façon asynchrone, cet état peut changer entre le moment où l’utilisateur a exécuté la commande et le gestionnaire de commandes en cours d’exécution. Consultez les contextes du client.

Exemple

Le Command constructeur a également besoin d’un constructeur qui accepte l’objet (qui autorise la VisualStudioExtensibility communication avec l’IDE) et une méthode ExecuteCommandAsyncd’exécution. L’exemple suivant fournit une implémentation minimale d’une commande générique qui ne fait rien :

[VisualStudioContribution]
public class MyCommand : Command
{
    /// <inheritdoc />
    public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%");

    public MyCommand(VisualStudioExtensibility extensibility)
        : base(extensibility)
    {
    }

    public override Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

Placer une commande dans l’IDE

Il existe un ensemble d’emplacements bien définis dans Visual Studio où les commandes peuvent être placées. Ces placements sont définis par la propriété KnownPlacements sur la classe CommandPlacement. L’ensemble actuel est KnownPlacements :

  • ToolsMenu - La commande est placée dans un groupe sous le menu « Outils » de niveau supérieur dans Visual Studio.
  • ViewOtherWindowsMenu - La commande est placée dans un groupe sous le menu « Affichage » de niveau supérieur -> « Autres fenêtres » dans Visual Studio.
  • ExtensionsMenu - La commande est placée dans un groupe sous le menu « Extensions » de niveau supérieur dans Visual Studio.

Les commandes peuvent également être placées à l’aide de la CommandPlacement.VsctParent méthode en spécifiant le Guid groupe Id défini via VSCT.

Les commandes parentées au même groupe sont triées en fonction de la propriété de Priority leur placement, par rapport à d’autres commandes ou menus avec le même placement. La valeur par défaut d’un CommandPlacement est 0 et peut être modifiée en appelant la CommandPlacement.WithPriority méthode, en passant la valeur souhaitéePriority.Priority

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    // The command will be parented to a group inside of the "Tools" top level menu,
    // a group inside of the "Extensions" top level menu, and the "About" group inside of the "Help" top level menu
    Placements = new CommandPlacement[]
    {
        CommandPlacement.KnownPlacements.ToolsMenu,
        CommandPlacement.KnownPlacements.ExtensionsMenu.WithPriority(0x0100),
        CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 0x016B, priority: 0x0801),
    },
};

Ajouter une icône à une commande

Les commandes prennent en charge l’ajout d’icônes à leur élément de menu, en plus ou au lieu du nom complet de la commande. Pour ajouter une icône à votre commande, définissez la Icon propriété sur la commande .CommandConfiguration

CommandIconConfiguration

Les deux paramètres sont les CommandIconConfiguration suivants :

Paramètre Type Requise Description
IconName ImageMoniker Oui Vous pouvez utiliser un moniker personnalisé pour une image que vous avez ajoutée après la section Ajout d’images personnalisées ou référencer un imageMoniker Visual Studio commeImageMonikers.KnownValues.AddItem
Icône Paramètres Icône Paramètres Oui Configure la façon dont la commande sera affichée. Par exemple IconSettings.IconAndText , affiche l’icône en même temps que le nom d’affichage de la commande, alors qu’elle IconSettings.IconOnly affiche uniquement l’icône de la commande et non son DisplayName s’il est parenté d’une barre d’outils.

Exemple ImageMoniker.KnownValues

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    Icon = new CommandIconConfiguration(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
};

Utiliser une image personnalisée pour l’icône de commande

Vous pouvez ajouter des images personnalisées, que vous pouvez ensuite référencer avec des monikers personnalisés en procédant comme suit :

  1. Renommez les fichiers sources d’image pour suivre le %Custom Moniker%.* modèle (par exemple, MyImage.1.png). Les fichiers préfixés avec le même moniker sont tous utilisés comme sources de stockage pour le même moniker personnalisé. Différentes sources seront utilisées en fonction de la taille d’icône demandée.
    • Par exemple, MyImage.16.16.png (a 16*16 png), MyImage.20.20.png (a 20*20 png) et MyImage.xaml sont tous considérés comme des sources pour MyImage.
    • Lorsque la taille d’icône demandée est 16*16, MyImage.16.16.png sera utilisée, lorsque la taille demandée est 20*20, MyImage.20.20.png sera utilisée, dans tous les autres cas, MyImage.xaml sera utilisé.
  2. Placez tous les fichiers sources d’image dans Images le dossier.
    • Le dossier des ressources d’image par défaut est Images, mais vous pouvez également le personnaliser en ajoutant <ImageAssetsPath>%YourFolder%</ImageAssetsPath>

Exemple ImageMoniker.Custom

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    Icon = new CommandIconConfiguration(ImageMoniker.Custom("MyImage"), IconSettings.IconAndText),
};

Raccourcis

Les commandes peuvent être configurées pour être exécutées lorsqu’une combinaison de touches spécifique est utilisée. Un raccourci se compose d’un ou deux chords, où chaque chord se compose d’un ModifierKey et d’un Key. Les valeurs possibles sont LeftAltModifierKey , , ControlShift, ControlShift, ControlShiftLeftAltet , NoneNoneest valide uniquement lorsqu’elles sont utilisées dans la deuxième corde d’un raccourci. La même ModifierKey chose n’a pas besoin d’être utilisée pour les deux chords dans un raccourci. L’utilisation Key dans un chord peut être presque n’importe quelle autre touche de clavier.

De nombreux raccourcis clavier sont déjà utilisés dans Visual Studio. Vous ne devez pas affecter le même raccourci à plusieurs commandes, car les liaisons en double sont difficiles à détecter et peuvent également entraîner des résultats imprévisibles. Par conséquent, il est judicieux de vérifier la disponibilité d’un raccourci avant de l’affecter.

Contrainte d’activation de raccourci

Une contrainte d’activation peut être incluse dans la configuration pour que le raccourci soit disponible dans différents contextes. Ces contraintes d’activation sont définies sous la forme d’un Guidéditeur et sont généralement liées à un éditeur. Lorsqu’un raccourci reçoit une contrainte d’activation, il est disponible uniquement dans ce contexte spécifique. Par exemple, utilisez « Guid {5EFC7975-14BC-11CF-9B2B-00AA00573819} » pour rendre le raccourci disponible dans l’éditeur Visual Studio. Dans ce cas, le raccourci n’est disponible que lorsque l’éditeur Visual Studio est concentré.

Exemple de raccourci

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    Shortcuts = new CommandShortcutConfiguration[]
    {
        new(ModifierKey.LeftAlt, Key.M),
        new(ModifierKey.ControlShift, Key.Y, ModifierKey.ControlShift, Key.B),
    },
};

Configurer une commande

Vous pouvez configurer la visibilité et l’état activé/désactivé d’une commande et définir des métadonnées supplémentaires à l’aide d’indicateurs.

Visibilité

La visibilité d’une commande peut être contrôlée en définissant la VisibleWhen propriété sur la commande .CommandConfiguration

L’attribut prend en charge la spécification d’une condition par le biais d’un certain nombre de paramètres individuels qui spécifient ensemble la condition et toutes ses logiques et entrées. Pour spécifier la condition, vous spécifiez une expression dans un paramètre, définissez un ensemble de termes (chaînes) utilisés dans l’expression dans un autre paramètre et quelles valeurs ces termes doivent être remplacés lors de l’évaluation dans un troisième paramètre. La combinaison de l’expression, des termes et des valeurs est appelée contrainte d’activation basée sur des règles et est entièrement décrite dans les contraintes d’activation basées sur des règles.

Si cette propriété est omise de votre configuration, la valeur par défaut est que la commande soit toujours visible.

Exemple de visibilité

public override CommandConfiguration CommandConfiguration => new("My command")
{
    VisibleWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, @"\.(jpg|jpeg|txt)$"),
};

État activé/désactivé

L’état activé/désactivé d’une commande peut être contrôlé en définissant la EnabledWhen propriété sur la commande .CommandConfiguration

Ce type de configuration est appelé contrainte d’activation basée sur des règles et est entièrement décrit à l’aide de contraintes d’activation basées sur des règles.

Si cette configuration est omise à partir de votre commande, la valeur par défaut est que la commande soit toujours activée. Vous pouvez également désactiver automatiquement votre commande si elle est en cours d’exécution en définissant this.DisableDuringExecution = true; le constructeur de votre classe de commandes. La définition de cette propriété remplace l’état activé/désactivé défini par la EnabledWhen configuration pendant l’exécution de la commande.

Exemple d’état activé/désactivé

public override CommandConfiguration CommandConfiguration => new("My command")
{
    EnabledWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, @"\.(jpg|jpeg|txt)$"),
};

Pour plus d’informations sur les valeurs de terme valides, consultez les contraintes d’activation basées sur des règles.

Indicateurs de commande

Les indicateurs de commande permettent de définir des propriétés supplémentaires sur vos commandes utilisées au moment de l’exécution pour définir des comportements spéciaux que votre commande peut avoir. Les indicateurs actuellement pris en charge sont les suivants :

  • CanToggle - Indique que la IsChecked propriété de la commande peut changer afin que les lecteurs d’écran puissent annoncer correctement la commande. Fonctionnellement, elle garantit que la propriété IsTogglePatternAvailable Automation retourne true pour l’élément d’interface utilisateur.
  • CanSelect - Indique que la IsChecked propriété de la commande peut changer afin que les lecteurs d’écran puissent annoncer correctement la commande. Fonctionnellement, elle garantit que la propriété IsSelectionPatternAvailable Automation retourne true pour l’élément d’interface utilisateur.

Modifier le nom complet d’une commande

Bien que le nom d’affichage d’une commande soit initialement défini dans le CommandConfiguration fichier (voir Création d’une commande), il peut être modifié au moment de l’exécution en définissant la DisplayName propriété dans votre commande. La ToolTipText propriété peut être mise à jour de la même façon.

Modifier l’exemple DisplayName

[VisualStudioContribution]
public class MyCommand : Command
{
    /// <inheritdoc />
    public override CommandConfiguration CommandConfiguration => new("Initial Display Name");

    public MyCommand(VisualStudioExtensibility extensibility)
     : base(extensibility)
    {
    }

    public override Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
    {
        // Update the command's Display Name
        this.DisplayName = "Updated Display Name";
        return Task.CompletedTask;
    }
}

Étapes suivantes