Como: criar e manipular comandos em VSPackages (C#)
Adicionar um comando a um VSPackage é um processo de duas etapas. Primeiro, o comando é definido como um elemento XML no arquivo .vsct. Em seguida, ele é implementado no código. As informações inseridas no arquivo .vsct determinam a aparência do comando, o posicionamento em um ambiente de desenvolvimento integrado (IDE) e alguns de seus comportamentos. O comando é definido no código, geralmente como um MenuCommand ou um OleMenuCommand objeto e seus manipuladores de eventos são implementados.
Os comandos que um VSPackage disponibiliza para o IDE deve ser visível e ativado antes que um usuário podem usá-los. Quando os comandos são criados em um arquivo de .vsct usando o modelo de projeto do pacote de Visual Studio, eles são visível e ativado por padrão. Definir alguns sinalizadores de comando, como DynamicItemStart, pode alterar o comportamento padrão. A visibilidade, status ativado e outras propriedades de um comando também poderá ser alteradas no código em tempo de execução, acessando o OleMenuCommand o objeto que está associado com o comando.
Criando um comando
Todos os comandos, os grupos de comando, menus, barras de ferramentas e janelas de ferramentas são definidas no arquivo .vsct. Se seu VSPackage não tiver um arquivo de .vsct, você deve adicionar um. Para obter mais informações, consulte Tabela Visual Studio de comando (.Arquivos de VSCT).
Se você estiver criando um VSPackage usando o modelo de pacote, selecione Comando de Menu para criar um arquivo de .vsct e definir um comando de menu padrão. Para obter mais informações, consulte Passo a passo: Criando um comando de Menu usando o modelo de pacote de Visual Studio.
Para adicionar um comando ao IDE
Abra o arquivo .vsct.
No Symbols seção, encontrar o GuidSymbol elemento que contém os comandos e grupos.
Criar um IDSymbol elemento para cada menu, grupo ou comando que você deseja adicionar, conforme mostrado no exemplo a seguir.
<GuidSymbol name="guidButtonGroupCmdSet" value="{f69209e9-975a-4543-821d-1f4a2c52d737}"> <IDSymbol name="MyMenuGroup" value="0x1020" /> <IDSymbol name="cmdidMyCommand" value="0x0100" /> </GuidSymbol>
O name atributos da GuidSymbol e IDSymbol elementos fornecem o par de GUID:ID para cada novo menu, um grupo ou um comando. O guid representa um conjunto de comandos que é definido para o VSPackage. Você pode definir vários conjuntos de comandos. Cada par de GUID:ID deve ser exclusivo.
No botões seção, criar um botão elemento para definir o comando, conforme mostrado no exemplo a seguir.
<Button guid="guidButtonGroupCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button"> <Parent guid="guidButtonGroupCmdSet" id="MyMenuGroup" /> <Icon guid="guidImages" id="bmpPic1" /> <Strings> <CommandName>cmdidMyCommand</CommandName> <ButtonText>My Command name</ButtonText> </Strings> </Button>
Definir o guid e id campos para coincidir com o GUID:ID do novo comando.
Defina o atributo priority.
O priority atributo é usado pelo .vsct para determinar o local do botão entre os outros objetos em seu grupo pai.
Comandos que têm valores de prioridade inferiores são exibidos acima ou à esquerda dos comandos que têm valores de prioridade mais altos. Valores de prioridade duplicados serão permitidos, mas a posição relativa de comandos que têm prioridade igual é determinada pela ordem na qual os VSPackages são processados em tempo de execução e ordem não pode ser predeterminada.
Omitindo o priority atributo define seu valor como 0.
Defina o atributo type. Na maioria dos casos, seu valor será "Button". Para obter descrições de outros tipos de botão válidos, consulte Elemento button.
Na definição do botão, crie um seqüências elemento que contém um texto de botão elemento para conter o nome do menu que aparece no IDE e um CommandName elemento para conter o nome do comando que é usado para acessar o menu no comando janela.
Se a seqüência de caracteres de texto do botão inclui o caractere '&', o usuário pode abrir o menu pressionando ALT mais o caractere ou imediatamente posterior a 'e'.
Adicionando um Tooltip elemento fará com que o texto contido apareça quando o usuário posiciona o ponteiro sobre o botão.
Adicionar um ícone elemento para especificar o ícone, se houver, para ser exibido com o comando. Ícones são necessários para os botões nas barras de ferramentas, mas não para itens de menu. O guid e id da Icon elemento deve corresponder às de um Bitmap elemento definido na Bitmaps seção.
Adicione sinalizadores de comando, conforme apropriado, para alterar a aparência e comportamento do botão. Para fazer isso, adicione um CommandFlag elemento na definição do menu.
Defina o grupo pai do comando. O grupo pai pode ser um grupo que você cria, um grupo de outro pacote ou um grupo a partir do IDE. Por exemplo, para adicionar ao lado de seu comando barra de ferramentas edição a Visual Studio, o comentário e Remover comentário botões, definir o pai para guidStdEditor:IDG_VS_EDITTOOLBAR_COMMENT. Se o pai for um grupo definido pelo usuário, ele deve ser o filho de um menu, barra de ferramentas ou janela de ferramenta que aparece no IDE.
Você pode fazer isso de duas maneiras, dependendo do seu design:
No Button elemento, criar um pai elemento e o conjunto de seus guid e id campos para o Guid e a identificação do grupo que irá hospedar o comando, também conhecido como o grupo pai principal.
O exemplo a seguir define um comando que será exibido em um menu definido pelo usuário.
<Button guid="guidTopLevelMenuCmdSet" id="cmdidTestCommand" priority="0x0100" type="Button"> <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" /> <Icon guid="guidImages" id="bmpPic1" /> <Strings> <CommandName>cmdidTestCommand</CommandName> <ButtonText>Test Command</ButtonText> </Strings> </Button>
Você pode omitir a Parent elemento se o comando deve ser posicionado, usando o posicionamento de comando. Criar um CommandPlacements elemento antes do Symbols seção e, em seguida, adicione um CommandPlacement elemento que tenha o guid e id do comando, um prioritye pai, conforme mostrado no exemplo a seguir.
<CommandPlacements> <CommandPlacement guid="guidButtonGroupCmdSet" id="cmdidMyCommand" priority="0x105"> <Parent guid="guidButtonGroupCmdSet" id="MyMenuGroup" /> </CommandPlacement> </CommandPlacements>
Criar várias posições de comando que têm o mesmo GUID:ID e tem pais diferentes faz com que um menu seja exibido em vários locais. Para obter mais informações, consulte CommandPlacements elemento.
Para obter mais informações sobre grupos de comando e a elevação de nível, consulte Como: criar grupos reutilizáveis de botões.
Neste ponto, o comando será visível no IDE, mas não terá nenhuma funcionalidade. Se o comando foi criado pelo modelo de pacote, ele terá um manipulador de cliques que exibe uma mensagem por padrão.
O novo comando de manipulação.
A maioria dos comandos no código gerenciado podem ser manipuladas pela estrutura de pacote gerenciado (MPF), associando o comando com um MenuCommand objeto ou OleMenuCommand de objeto e implementar seus manipuladores de eventos.
Para o código que usa o IOleCommandTarget interface diretamente para a manipulação de comandos, você deve implementar a IOleCommandTarget interface e seus métodos. Os dois métodos mais importantes são QueryStatus e Exec.
Para lidar com o novo comando, usando o MPF
Obter o OleMenuCommandService da instância, conforme mostrado no exemplo a seguir.
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
Criar um CommandID o objeto que tenha como seus parâmetros GUID e ID do comando para manipular, conforme mostrado no exemplo a seguir.
CommandID menuCommandID = new CommandID(GuidList.guidButtonGroupCmdSet, (int)PkgCmdIDList.cmdidMyCommand);
O modelo de pacote de Visual Studio fornece duas coleções, GuidList e PkgCmdIDList, para manter as GUIDs e as identificações de comandos. Eles são preenchidos automaticamente para os comandos que são adicionados pelo modelo, mas para os comandos que você adiciona manualmente, você também deve adicionar a entrada de identificação para o PkgCmdIdList classe.
Como alternativa, você pode preencher o CommandID o objeto usando o valor bruto de seqüência de caracteres do GUID e o valor inteiro da ID.
Criar uma instância de um um MenuCommand ou OleMenuCommand objeto que especifica o método que manipula o comando junto com o CommandID, conforme mostrado no exemplo a seguir.
MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
O MenuCommand é apropriado para comandos estáticos. Exibe de item de menu dinâmico exige QueryStatus manipuladores de eventos. O OleMenuCommand adiciona a BeforeQueryStatus evento, que ocorre quando o menu de host do comando propriedades abertas e alguns outras, como Text.
Comandos criados pelo modelo de pacote são passados por padrão, um OleMenuCommand de objeto na Initialize() método da classe do pacote.
O MenuCommand é apropriado para comandos estáticos. Exibe de item de menu dinâmico exige QueryStatus manipuladores de eventos. O OleMenuCommand adiciona a BeforeQueryStatus evento, que ocorre quando o menu de host do comando propriedades abertas e alguns outras, como Text.
Comandos criados pelo modelo de pacote são passados por padrão, um OleMenuCommand de objeto na Initialize() método da classe do pacote. O assistente Visual Studio implementa o Initialize método usando MenuCommand. Para monitores de item de menu dinâmico, você deve alterá-la para OleMenuCommand, conforme é mostrado na próxima etapa. Além disso, para alterar o texto do item de menu, você deve adicionar um sinalizador de comando textoAltera para o botão de comando de menu no arquivo .vsct, tal como é mostrado no exemplo a seguir
<Button guid="guidMenuTextCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button"> <Parent guid="guidMenuTextCmdSet" id="MyMenuGroup" /> <Icon guid="guidImages" id="bmpPic1" /> <CommandFlag>TextChanges</CommandFlag> <Strings> <CommandName>cmdidMyCommand</CommandName> <ButtonText>My Command name</ButtonText> </Strings> </Button>
Passar o novo comando de menu para o AddCommand método na IMenuCommandService interface. Isso é realizado por padrão para comandos criados pelo modelo de pacote, conforme mostrado no exemplo a seguir
mcs.AddCommand( menuItem );
Implemente o método que manipula o comando.
Para implementar QueryStatus usando as classes do MPF
O evento QueryStatus ocorre antes que um comando seja exibido. Isso permite que propriedades de comando seja definido o manipulador antes que ele chegue ao usuário. Somente os comandos que são adicionados como OleMenuCommand objetos podem acessar esse método.
Adicionar um EventHandler o objeto para o BeforeQueryStatus evento na OleMenuCommand objeto é criado para lidar com o comando, conforme mostrado no exemplo a seguir (menuItem é o OleMenuCommand instância).
Dim menuCommandID As CommandID = New CommandID(GuidList.guidMenuTextCmdSet, CInt(PkgCmdIDList.cmdidMyTextCommand)) Dim menuItem As OleMenuCommand = New OleMenuCommand(New EventHandler(AddressOf MenuItemCallback), menuCommandID) AddHandler menuItem.BeforeQueryStatus, AddressOf OnBeforeQueryStatus mcs.AddCommand(menuItem)
// Create the command for the menu item. CommandID menuCommandID = new CommandID(GuidList.guidMenuTextCmdSet, (int)PkgCmdIDList.cmdidMyCommand); OleMenuCommand menuItem = new OleMenuCommand(MenuItemCallback, menuCommandID ); menuItem.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus); mcs.AddCommand(menuItem);
O EventHandler objeto recebe o nome de um método que é chamado quando o status do comando de menu é consultado.
Implemente o método do manipulador do status de consulta para o comando. O objectsender parâmetro pode ser convertido para um OleMenuCommand objeto, que é usado para definir os vários atributos do comando de menu, incluindo o texto. A tabela a seguir mostra as propriedades na MenuCommand classe (que a classe do MPF OleMenuCommand deriva) que correspondam ao OLECMDF sinalizadores.
Propriedade MenuCommand
Sinalizador OLECMDF
Checked = true
Visible = false
Enabled = true
Para alterar o texto de um comando de menu, use o Text propriedade no OleMenuCommand de objeto, conforme mostrado no exemplo a seguir.
Private Sub OnBeforeQueryStatus(ByVal sender As Object, ByVal e As EventArgs) Dim myCommand As OleMenuCommand = TryCast(sender, OleMenuCommand) If myCommand IsNot Nothing Then myCommand.Text = "New Text" End If End Sub
private void OnBeforeQueryStatus(object sender, EventArgs e) { var myCommand = sender as OleMenuCommand; if (null != myCommand) { myCommand.Text = "New Text"; } }
O MPF automaticamente manipula o caso dos grupos sem suporte ou desconhecidos. A menos que um comando foi adicionado para o OleMenuCommandService usando o AddCommand método, o comando não é suportado.
Manipulação de comandos usando a Interface IOleCommandTarget
Para o código que usa o IOleCommandTarget interface diretamente, o VSPackage deve implementar ambos o QueryStatus e Exec métodos para o IOleCommandTarget interface. Se o VSPackage implementa uma hierarquia de projeto, o QueryStatusCommand e ExecCommand métodos para o IVsUIHierarchy interface deve ser implementada em vez disso.
Tanto o QueryStatus e Exec métodos destinam-se para receber um conjunto único comando GUID e um array de IDs de comando como entrada. Recomendamos que os VSPackages suporte totalmente esse conceito de várias IDs em uma chamada. No entanto, enquanto um VSPackage não é chamado de outros VSPackages, você pode assumir que a matriz de comando contém apenas uma ID de comando porque a QueryStatus e Exec métodos são executados em uma ordem bem definida. Para obter mais informações sobre roteamento, consulte Command Routing in VSPackages.
Para o código que usa o IOleCommandTarget interface diretamente para a manipulação de comandos, você deve implementar a QueryStatus método em que o VSPackage da seguinte forma para manipular comandos.
Para implementar o método QueryStatus
Retornar S_OK para comandos válidos.
Definir o cmdf elemento da prgCmds parâmetro.
O valor da cmdf elemento é a união lógica de valores da OLECMDF enumeração, combinada, usando o (OR lógico|) operador.
Use a enumeração apropriada, com base no status do comando:
Se o comando é aceito:
prgCmds[0].cmdf = OLECMDF_SUPPORTED;
Se o comando deve ser invisível no momento:
prgCmds[0].cmdf |= OLECMDF_INVISIBLE;
Se o comando está alternado e parece ter sido clicado:
prgCmds[0].cmdf |= OLECMDF_LATCHED;
No caso do processamento de comandos que são hospedados em um menu do tipo MenuControllerLatched, o primeiro comando é marcado pela OLECMDF_LATCHED sinalizador é o comando padrão que é exibido pelo menu na inicialização. Para obter mais informações sobre MenuController tipos de menu, consulte Elemento menu.
Se o comando está ativado no momento:
prgCmds[0].cmdf |= OLECMDF_ENABLED;
Se o comando é parte de um menu de atalho e fica oculta por padrão:
prgCmds[0] cmdf |= OLECMDF_DEFHIDEONCTXMENU
Se o comando usa o TEXTCHANGES sinalizar, defina a rgwz elemento da pCmdText parâmetro para o novo texto de comando e do conjunto a cwActual elemento da pCmdText parâmetro para o tamanho da seqüência de caracteres de comando.
Para as condições de erro, o QueryStatus método deve tratar de casos de erro a seguir:
Se o GUID for desconhecido ou sem suporte, retorne OLECMDERR_E_UNKNOWNGROUP.
Se o GUID é conhecido, mas a identificação do comando é desconhecido ou sem suporte, retornar OLECMDERR_E_NOTSUPPORTED.
A implementação VSPackage a Exec método também deve retornar códigos de erro específicos, dependendo do suporte para o comando e se o comando foi tratado com êxito.
Para implementar o método Exec
Se o comando GUID é desconhecido, retornar OLECMDERR_E_UNKNOWNGROUP.
Se a GUID é conhecido, mas o comando ID é desconhecido, retornar OLECMDERR_E_NOTSUPPORTED.
Se a GUID e identificação coincide com o par de GUID:ID que é usado pelo comando no arquivo de .vsct de comando, execute o código que está associado com o comando e o retorno de S_OK.
Consulte também
Conceitos
Referência de esquema XML VSCT