Aggiungere comandi di Visual Studio

Un comando rappresentato dalla Command classe è un'azione che può essere avviata da un utente, ad esempio quando l'utente sceglie una voce di menu, preme un pulsante della barra degli strumenti o digita una scelta rapida da tastiera. I comandi hanno un nome visualizzato, un metodo di esecuzione (ExecuteCommandAsync) che esegue l'azione, un'icona da visualizzare sulla barra degli strumenti per identificare il comando e una descrizione comando per spiegare il comando all'utente. I comandi possono essere abilitati o disabilitati a seconda di varie condizioni.

I comandi nel nuovo modello di estendibilità vengono eseguiti in modo asincrono in modo che l'utente possa continuare a interagire con l'IDE durante l'esecuzione dei comandi.

Usare i comandi

Questa panoramica illustra questi scenari principali per l'uso dei comandi:

Creazione di un comando

La creazione di un comando con il nuovo modello di estendibilità inizia con l'estensione della classe Commanddi base , la struttura della classe con l'attributo e l'implementazione VisualStudioContribution della CommandConfiguration proprietà .

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

Classe CommandConfiguration

La CommandConfiguration classe ha alcuni parametri da acquisire familiarità con:

Parametro Type Obbligatorio Descrizione
DisplayName String Nome visualizzato predefinito del comando. Racchiudere questa stringa con il carattere '%' per abilitare la localizzazione di questa stringa. Vedere la sezione Localizzare i metadati.
ToolTipText String No Testo da visualizzare come descrizione comando quando il comando viene posizionato o attivo. Racchiudere questa stringa con il carattere '%' per abilitare la localizzazione di questa stringa. Vedere in Localizzare i metadati
Flag CommandFlags No Flag per impostare proprietà aggiuntive nel comando. Alcune opzioni includono CanToggle e CanSelect. Vedere flag di comando.
Posizionamenti CommandPlacement[] No Specifica i gruppi esistenti all'interno di Visual Studio a cui verrà padre il comando. Vedere Inserire un comando nell'IDE. Anche senza un posizionamento, il comando sarà comunque disponibile tramite la funzionalità Di ricerca di Visual Studio. I comandi possono anche essere posizionati in Menu, Barre degli strumenti e Gruppi definiti nell'estensione.
Icon CommandIconConfiguration No I comandi possono essere visualizzati nell'interfaccia utente come semplicemente un'icona, un'icona con testo o solo testo. Questa proprietà configura l'icona che deve essere, se presente, e come deve essere visualizzata.
Collegamenti CommandShortcutConfiguration[] No Definisce il set di combinazioni di tasti che possono essere usate per eseguire il comando. È possibile definire l'ambito dei collegamenti in modo che sia applicabile solo a contesti IDE specifici. Vedere collegamenti.
ClientContexts[] String No Contesti client richiesti dal comando . Per impostazione predefinita, vengono restituiti i contesti shell e editor. Un contesto client è uno snapshot di stati IDE specifici al momento dell'esecuzione di un comando. Poiché questi comandi vengono eseguiti in modo asincrono, questo stato potrebbe cambiare tra il momento in cui l'utente ha eseguito il comando e il gestore dei comandi in esecuzione. Vedere i contesti client.

Esempio

È Command inoltre necessario un costruttore che accetta l'oggetto VisualStudioExtensibility (che consente la comunicazione con l'IDE) e un metodo di ExecuteCommandAsyncesecuzione . L'esempio seguente fornisce un'implementazione minima di un comando generico che non esegue alcuna operazione:

[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;
    }
}

Inserire un comando nell'IDE

In Visual Studio è disponibile un set di posizioni ben definite in cui è possibile posizionare i comandi. Questi posizionamenti sono definiti dalla proprietà KnownPlacements nella classe CommandPlacement. Il set corrente di KnownPlacements è:

  • ToolsMenu - Il comando verrà inserito in un gruppo nel menu "Strumenti" di primo livello in Visual Studio.
  • ViewOtherWindowsMenu - Il comando verrà inserito in un gruppo sotto il menu "Visualizza" di primo livello -> "Altre finestre" in Visual Studio.
  • ExtensionsMenu - Il comando verrà inserito in un gruppo nel menu "Estensioni" di primo livello in Visual Studio.

I comandi possono anche essere posizionati usando il CommandPlacement.VsctParent metodo specificando e GuidId di gruppo definito tramite VSCT.

I comandi padre dello stesso gruppo vengono ordinati in base alla proprietà del Priority posizionamento, rispetto ad altri comandi o menu con la stessa posizione. Il valore predefinito Priority di un CommandPlacement oggetto è 0 e può essere modificato chiamando il CommandPlacement.WithPriority metodo , passando il valore desiderato 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),
    },
};

Aggiungere un'icona a un comando

I comandi supportano l'aggiunta di icone alla voce di menu, oltre che al nome visualizzato del comando. Per aggiungere un'icona al comando, impostare la Icon proprietà sul comando di CommandConfiguration.

CommandIconConfiguration

Ha CommandIconConfiguration due parametri:

Parametro Type Obbligatorio Descrizione
IconName ImageMoniker È possibile usare un moniker personalizzato per un'immagine aggiunta dopo la sezione Aggiunta di immagini personalizzate o fare riferimento a un oggetto ImageMoniker di Visual Studio, ad esempioImageMonikers.KnownValues.AddItem
Icona Impostazioni Icona Impostazioni Configura la modalità di visualizzazione del comando. Ad esempio IconSettings.IconAndText , visualizza l'icona accanto al nome visualizzato del comando, mentre IconSettings.IconOnly mostrerà solo l'icona del comando e non il relativo DisplayName se è padre di una barra degli strumenti.

Esempio imageMoniker.KnownValues

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

Usare un'immagine personalizzata per l'icona del comando

È possibile aggiungere immagini personalizzate, a cui è quindi possibile fare riferimento con moniker personalizzati seguendo questa procedura:

  1. Rinominare i file di origine dell'immagine in modo che seguano il %Custom Moniker%.* modello ,ad esempio MyImage.1.png. I file preceduti dallo stesso moniker verranno usati tutti come origini di backup per lo stesso moniker personalizzato. Verrà usata un'origine diversa in base alle dimensioni dell'icona richieste.
    • Ad esempio, MyImage.16.16.png (16*16 png), MyImage.20.20.png (a 20*20 png) e MyImage.xaml sono tutti considerati come origini per MyImage.
    • Quando la dimensione dell'icona richiesta è 16*16, verrà usato MyImage.16.16.png, quando le dimensioni richieste sono pari a 20*20, verrà usato MyImage.20.20.png, in tutti gli altri casi verrà usato MyImage.xaml.
  2. Inserire tutti i file di origine dell'immagine nella Images cartella .
    • La cartella predefinita degli asset di immagine è Images, ma è anche possibile personalizzarla aggiungendo <ImageAssetsPath>%YourFolder%</ImageAssetsPath>

Esempio imageMoniker.Custom

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

Collegamenti

I comandi possono essere configurati per l'esecuzione quando viene usata una combinazione di tasti specifica. Un collegamento è costituito da uno o due accordi, dove ogni accordo è costituito da un ModifierKey e uno Key. I valori possibili per ModifierKey sono LeftAlt, Shift, ControlShiftControl, ControlShiftLeftAlt, e None, dove None è valido solo quando viene usato nel secondo accordo di un collegamento. Lo stesso ModifierKey non deve essere usato per entrambi gli accordi in un collegamento. L'oggetto Key utilizzato in un accordo può essere quasi qualsiasi altro tasto della tastiera.

Molti tasti di scelta rapida sono già usati in Visual Studio. Non è consigliabile assegnare lo stesso collegamento a più comandi perché le associazioni duplicate sono difficili da rilevare e possono causare risultati imprevedibili. Pertanto, è consigliabile verificare la disponibilità di un collegamento prima di assegnarlo.

Vincolo di attivazione del collegamento

Un vincolo di attivazione può essere incluso nella configurazione per rendere disponibile il collegamento in contesti diversi. Questi vincoli di attivazione sono definiti sotto forma di e Guidin genere sono correlati a un editor. Quando viene assegnato un vincolo di attivazione, un collegamento sarà disponibile solo in tale contesto specifico. Ad esempio, usare Guid "{5EFC7975-14BC-11CF-9B2B-00AA00573819}" per rendere disponibile il collegamento nell'editor di Visual Studio. In questo caso il collegamento sarebbe disponibile solo quando l'editor di Visual Studio è attivo.

Esempio di collegamento

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

Configurare un comando

È possibile configurare la visibilità e lo stato abilitato/disabilitato di un comando e impostare metadati aggiuntivi usando i flag.

Visibilità

La visibilità di un comando può essere controllata impostando la VisibleWhen proprietà sul comando di CommandConfiguration.

L'attributo supporta la specifica di una condizione tramite un numero di singoli parametri che insieme specificano la condizione e tutti i relativi input e logica. Per specificare la condizione, specificare un'espressione in un parametro, definire un set di termini (stringhe) usati nell'espressione in un altro parametro e quali valori devono essere sostituiti con al momento della valutazione in un terzo parametro. La combinazione di espressioni, termini e valori è detta vincolo di attivazione basata su regole ed è descritta in Modo completo in Vincoli di attivazione basati su regole.

Se questa proprietà viene omessa dalla configurazione, il valore predefinito è che il comando sia sempre visibile.

Esempio di visibilità

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

Stato abilitato/disabilitato

Lo stato abilitato/disabilitato di un comando può essere controllato impostando la proprietà sul EnabledWhen comando .CommandConfiguration

Questo tipo di configurazione è denominato vincolo di attivazione basato su regole ed è descritto in Uso dei vincoli di attivazione basati su regole.

Se questa configurazione viene omessa dal comando, l'impostazione predefinita è che il comando sia sempre abilitato. È anche possibile disabilitare automaticamente il comando se è attualmente in esecuzione impostando this.DisableDuringExecution = true; nel costruttore della classe di comando. L'impostazione di questa proprietà esegue l'override dello stato abilitato/disabilitato definito dalla configurazione durante l'esecuzione EnabledWhen del comando.

Esempio di stato abilitato/disabilitato

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

Per altre informazioni sui valori validi dei termini, vedere Vincoli di attivazione basati su regole.

Flag di comando

I flag di comando consentono di definire proprietà aggiuntive nei comandi usati in fase di esecuzione per definire comportamenti speciali che il comando può avere. I flag attualmente supportati sono:

  • CanToggle - Indica che la IsChecked proprietà del comando può cambiare in modo che le utilità per la lettura dello schermo possano annunciare correttamente il comando. In modo funzionale, garantisce che la proprietà IsTogglePatternAvailable di automazione restituisca true per l'elemento dell'interfaccia utente.
  • CanSelect - Indica che la IsChecked proprietà del comando può cambiare in modo che le utilità per la lettura dello schermo possano annunciare correttamente il comando. In modo funzionale, garantisce che la proprietà IsSelectionPatternAvailable di automazione restituisca true per l'elemento dell'interfaccia utente.

Modificare il nome visualizzato di un comando

Anche se il nome visualizzato per un comando è inizialmente impostato in CommandConfiguration (vedere Creazione di un comando), può essere modificato in fase di esecuzione impostando la DisplayName proprietà nel comando. La ToolTipText proprietà può essere aggiornata in modo simile.

Esempio di modifica di 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;
    }
}

Passaggi successivi