Adicionar comandos do Visual Studio

Um comando representado pela Command classe é alguma ação que pode ser iniciada por um usuário, como quando o usuário escolhe um item de menu, pressiona um botão da barra de ferramentas ou digita um atalho de teclado. Os comandos têm um nome para exibição, um método de execução (ExecuteCommandAsync) que executa a ação, um ícone para exibição na barra de ferramentas para identificar o comando e uma dica de ferramenta para explicar o comando ao usuário. Os comandos podem ser habilitados ou desabilitados dependendo de várias condições.

Os comandos no novo Modelo de Extensibilidade são executados de forma assíncrona para que o usuário possa continuar a interagir com o IDE enquanto os comandos estão sendo executados.

Trabalhar com comandos

Esta visão geral aborda estes principais cenários para trabalhar com comandos:

Criar um comando

A criação de um comando com o novo Modelo de Extensibilidade começa com a extensão da classe base, adornando a classe Commandcom o VisualStudioContribution atributo e implementando a CommandConfiguration propriedade.

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

CommandConfiguration classe

A CommandConfiguration classe tem alguns parâmetros com os quais você deve se familiarizar:

Parâmetro Type Obrigatória Descrição
DisplayName String Sim O nome de exibição padrão do comando. Envolva essa cadeia de caracteres com o caractere '%' para habilitar a localização dessa cadeia de caracteres. Consulte em Localizar metadados.
ToolTipText String Não O texto a ser exibido como a dica de ferramenta quando o comando estiver focalizado ou focalizado. Envolva essa cadeia de caracteres com o caractere '%' para habilitar a localização dessa cadeia de caracteres. Consulte em Localizar metadados
Sinalizadores CommandFlags Não Sinalizadores para definir propriedades adicionais no comando. Algumas opções incluem CanToggle e CanSelect. Veja em Sinalizadores de comando.
Posicionamentos CommandPlacement[] Não Especifica os grupos existentes no Visual Studio para os quais o comando será parentado. Consulte em Colocar um comando no IDE. Mesmo sem um posicionamento, seu comando ainda estará disponível por meio do recurso de pesquisa do Visual Studio. Os comandos também podem ser colocados em Menus, Barras de Ferramentas e Grupos definidos em sua extensão.
Ícone CommandIconConfiguration Não Os comandos podem ser exibidos na interface do usuário como apenas um ícone, um ícone com texto ou apenas texto. Essa propriedade configura o que esse ícone deve ser, se houver, e como ele deve ser exibido.
Atalhos CommandShortcutConfiguration[] Não Define o conjunto de combinações de teclas que podem ser usadas para executar o comando. Os atalhos podem ter o escopo reduzido para serem aplicáveis apenas a contextos específicos do IDE. Veja em Atalhos.
ClientContexts[] String Não Contextos de cliente solicitados pelo comando. Por padrão, os contextos Shell e Editor são retornados. Um contexto de cliente é um instantâneo de estados específicos do IDE no momento em que um comando foi originalmente executado. Como esses comandos são executados de forma assíncrona, esse estado pode mudar entre o momento em que o usuário executou o comando e o manipulador de comandos em execução. Veja em Contextos do cliente.

Exemplo

O Command também precisa de um construtor que pegue o objeto (que permite a comunicação com o VisualStudioExtensibility IDE), e um método ExecuteCommandAsyncde execução. O exemplo a seguir fornece uma implementação mínima de um comando genérico que não faz nada:

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

Colocar um comando no IDE

Há um conjunto de locais bem definidos no Visual Studio onde os comandos podem ser colocados. Esses posicionamentos são definidos pela propriedade KnownPlacements na classe CommandPlacement. O conjunto atual de KnownPlacements é:

  • ToolsMenu - O comando será colocado em um grupo sob o menu de nível superior "Ferramentas" no Visual Studio.
  • ViewOtherWindowsMenu - O comando será colocado em um grupo sob o nível superior "View" -> "Other Windows" menu no Visual Studio.
  • ExtensionsMenu - O comando será colocado em um grupo sob o menu de nível superior "Extensões" no Visual Studio.

Os comandos também podem ser colocados usando o CommandPlacement.VsctParent método especificando o Guid e Id do grupo definido via VSCT.

Os comandos parentais do mesmo grupo são classificados com base na propriedade do Priority posicionamento, em relação a outros comandos ou menus com o mesmo posicionamento. O valor padrão Priority para a CommandPlacement é 0 e pode ser modificado chamando o método, passando o CommandPlacement.WithPriority valor desejado 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),
    },
};

Adicionar um ícone a um comando

Os comandos oferecem suporte à adição de ícones ao item de menu, além ou em vez do nome de exibição do comando. Para adicionar um ícone ao comando, defina a Icon propriedade no arquivo CommandConfiguration.

CommandIconConfiguration

O CommandIconConfiguration tem dois parâmetros:

Parâmetro Type Obrigatória Descrição
Nome do ícone ImageMoniker Sim Você pode usar um moniker personalizado para uma imagem adicionada após a seção Adicionando imagens personalizadas ou fazer referência a um Visual Studio ImageMoniker como ImageMonikers.KnownValues.AddItem
IconSettings IconSettings Sim Configura como o comando será exibido. Por exemplo IconSettings.IconAndText , exibe o ícone ao lado do nome de exibição do comando, enquanto IconSettings.IconOnly mostrará apenas o ícone do comando e não seu DisplayName se for pai de uma barra de ferramentas.

Exemplo de ImageMoniker.KnownValues

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

Usar uma imagem personalizada para o ícone de comando

Você pode adicionar imagens personalizadas, que você pode referenciar com monikers personalizados seguindo estas etapas:

  1. Renomeie os arquivos de origem da imagem para seguir o %Custom Moniker%.* padrão (por exemplo, MyImage.1.png). Arquivos prefixados com o mesmo moniker serão todos usados como fontes de suporte para o mesmo moniker personalizado. Fontes diferentes serão usadas com base no tamanho do ícone solicitado.
    • Por exemplo, MyImage.16.16.png (um png de 16 * 16 ), MyImage.20.20.png (um png de 20 * 20) e MyImage.xaml são todos considerados fontes para MyImageo .
    • Quando o tamanho do ícone solicitado for 16*16, MyImage.16.16.png será usado, quando o tamanho solicitado for 20*20, MyImage.20.20.png será usado, em todos os outros casos, MyImage.xaml será usado.
  2. Coloque todos os arquivos de origem da imagem na Images pasta.
    • A pasta de ativos de imagem padrão é Images, mas você também pode personalizá-la adicionando <ImageAssetsPath>%YourFolder%</ImageAssetsPath>

Exemplo de ImageMoniker.Custom

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

Atalhos

Os comandos podem ser configurados para serem executados quando uma combinação de teclas específica é usada. Um atalho consiste em um ou dois acordes, onde cada acorde consiste em um e um ModifierKeyKey. Os valores possíveis para ModifierKey são LeftAlt, , , , ControlShiftLeftAlt, e , ControlShiftNoneShiftControlonde None só é válido quando usado no segundo acorde de um atalho. O mesmo ModifierKey não precisa ser usado para ambos os acordes em um atalho. O Key usado em um acorde pode ser quase qualquer outra tecla de teclado.

Muitos atalhos de teclado já são usados no Visual Studio. Você não deve atribuir o mesmo atalho a mais de um comando porque associações duplicadas são difíceis de detectar e também podem causar resultados imprevisíveis. Portanto, é uma boa ideia verificar a disponibilidade de um atalho antes de atribuí-lo.

Restrição de ativação de atalho

Uma restrição de ativação pode ser incluída na configuração para ter o atalho disponível em diferentes contextos. Essas restrições de ativação são definidas na forma de um , e geralmente se relacionam a um Guideditor. Quando um atalho recebe uma restrição de ativação, ele só estará disponível nesse contexto específico. Por exemplo, use o "{5EFC7975-14BC-11CF-9B2B-00AA00573819}" para disponibilizar o Guid atalho no editor do Visual Studio. Nesse caso, o atalho só estaria disponível quando o editor do Visual Studio está focado.

Exemplo de atalho

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

Configurar um comando

Você pode configurar a visibilidade e o estado habilitado/desabilitado de um comando e definir metadados adicionais usando sinalizadores.

Visibilidade

A visibilidade de um comando pode ser controlada definindo a VisibleWhen propriedade no .CommandConfiguration

O atributo oferece suporte à especificação de uma condição por meio de vários parâmetros individuais que, juntos, especificam a condição e todas as suas lógicas e entradas. Para especificar a condição, especifique uma expressão em um parâmetro, defina um conjunto de termos (cadeias de caracteres) usados na expressão em outro parâmetro e quais valores esses termos devem ser substituídos após a avaliação em um terceiro parâmetro. A combinação da expressão, termos e valores é chamada de restrição de ativação baseada em regra e é totalmente descrita em Restrições de ativação baseadas em regras.

Se essa propriedade for omitida da configuração, o padrão é que o comando esteja sempre visível.

Exemplo de visibilidade

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

Estado habilitado/desabilitado

O estado habilitado/desabilitado de um comando pode ser controlado definindo a EnabledWhen propriedade no arquivo CommandConfiguration.

Esse tipo de configuração é chamado de restrição de ativação baseada em regra e é descrito completamente em Usando restrições de ativação baseadas em regras.

Se essa configuração for omitida do comando, o padrão é que o comando esteja sempre habilitado. Você também pode desativar automaticamente seu comando se ele estiver em execução no momento, definindo this.DisableDuringExecution = true; no construtor de sua classe de comando. A definição dessa propriedade substitui o estado habilitado/desabilitado definido pela EnabledWhen configuração enquanto o comando está sendo executado.

Exemplo de estado habilitado/desabilitado

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

Para obter mais informações sobre valores de termo válidos, consulte Restrições de ativação baseadas em regras.

Sinalizadores de comando

Os sinalizadores de comando ajudam a definir propriedades adicionais em seus comandos que são usados em tempo de execução para definir comportamentos especiais que seu comando pode ter. Os sinalizadores atualmente suportados são:

  • CanToggle - Indica que a propriedade do comando pode mudar para que os IsChecked leitores de tela possam anunciar o comando corretamente. Funcionalmente, ele garante que a propriedade IsTogglePatternAvailable de automação retorne true para o elemento da interface do usuário.
  • CanSelect - Indica que a propriedade do comando pode mudar para que os IsChecked leitores de tela possam anunciar o comando corretamente. Funcionalmente, ele garante que a propriedade IsSelectionPatternAvailable de automação retorne true para o elemento da interface do usuário.

Alterar o nome de exibição de um comando

Embora o nome para exibição de um comando seja inicialmente definido no CommandConfiguration (consulte Criando um comando), ele pode ser alterado em tempo de execução definindo a DisplayName propriedade em seu comando. A ToolTipText propriedade pode ser atualizada de forma semelhante.

Exemplo de alteração de 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;
    }
}

Próximas etapas