Como: adicionar um comando ao Menu de atalho
Você pode adicionar comandos de menu para sua linguagem específica de domínio (DSL) para que os usuários podem executar tarefas que são específicas para seu DSL.Os comandos aparecem no menu de contexto (atalho) quando os usuários com o botão direito no diagrama.Você pode definir um comando para que ela só apareça no menu em circunstâncias específicas.Por exemplo, o comando poderá tornar visível apenas quando o usuário clica em tipos específicos de elemento ou elementos em estados específicos.
Em resumo, as etapas são executadas no projeto DslPackage, da seguinte maneira:
Declarar o comando no Commands.vsct
Atualizar o número de versão do pacote no Package.tt.Você precisa fazer isso, sempre que você alterar o Commands.vsct
Escrever métodos na classe CommandSet para fazer com que o comando visível e para definir o que deseja que o comando para realizar.
Para obter exemplos, consulte o site de visualização e modelagem SDK.
Observação |
---|
Você também pode modificar o comportamento de alguns comandos existentes como, por exemplo, recortar, colar, selecionar tudo e impressão, substituindo os métodos em CommandSet.cs.Para obter mais informações, consulte Como: modificar um comando de Menu padrão em um idioma específico do domínio. |
Definindo um comando usando MEF
Framework de extensão gerenciados (MEF) fornece um método alternativo de definir os comandos de menu no menu diagrama.Sua finalidade principal é permitir uma DSL ser estendida por você ou por terceiros.Os usuários podem optar por instalar apenas o DSL ou podem instalar o DSL e extensões.No entanto, o MEF também reduz o trabalho de definir os comandos de menu de atalho, após o trabalho inicial para ativar MEF em DSL.
Use o método neste tópico se:
Você deseja definir os comandos de menu nos menus diferente no menu de atalho com o botão direito.
Você deseja definir agrupamentos específicos de comandos no menu.
Você não deseja permitir que outras pessoas estender o DSL com seus próprios comandos.
Somente você deseja definir um único comando.
Caso contrário, considere o uso o método MEF para definir comandos.Para obter mais informações, consulte Estender seu DSL usando MEF.
Declarar o comando no Commands.Vsct
Comandos de menu são declarados no DslPackage\Commands.vsct.Essas definições especificam os rótulos dos itens de menu e onde eles aparecem nos menus.
O arquivo que você edita, Commands.vsct, importa a definições de vários arquivos. h, que estão localizados no diretório caminho de instalação do SDK do Visual Studio\VisualStudioIntegration\Common\Inc.Ele também inclui GeneratedVsct.vsct, que é gerado a partir de sua definição de DSL.
Para obter mais informações sobre arquivos de .vsct, consulte Tabela Visual Studio de comando (.Arquivos de VSCT).
Para adicionar o comando
Em Solution Explorer, no DslPackage de projeto, abra Commands.vsct.
No Commands elemento, definir um ou mais botões e um grupo.A botão é um item no menu.A grupo é uma seção no menu.Para definir esses itens, adicione os seguintes elementos:
<!-- 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>
Observação Cada botão ou o grupo é identificado por um GUID e um ID de inteiro.Você pode criar vários grupos e botões com a mesma GUID.No entanto, eles devem ter uma identificação diferente.Os nomes GUID e ID são traduzidas para GUIDs de reais e IDs numéricas na <Symbols> nó.
Adicione uma restrição de visibilidade para o comando para que ele é carregado somente no contexto de sua linguagem específica de domínio.Para obter mais informações, consulte Elemento de VisibilityConstraints.
Para fazer isso, adicione os seguintes elementos de CommandTable elemento após o Commands elemento.
<VisibilityConstraints> <!-- Ensures the command is only loaded for this DSL --> <VisibilityItem guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand" context="guidEditor"/> </VisibilityConstraints>
Defina os nomes que você usou para o ids e guids.Para fazer isso, adicione um Symbols elemento a CommandTable elemento após o Commands elemento.
<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>
Substitua {000...000} com um GUID que identifica os grupos e os itens de menu.Para obter um novo GUID, use o Criar GUID ferramenta na Ferramentas menu.
Observação Se você adicionar mais grupos ou itens de menu, você pode usar a mesma GUID.Entretanto, você deve usar os novos valores para o IDSymbols.
O código que você copiou neste procedimento, substitua cada ocorrência das seguintes seqüências com suas próprias seqüências de caracteres:
grpidMyMenuGroup
cmdidMyContextMenuCommand
guidCustomMenuCmdSet
Meu comando de Menu de contexto
Atualizar a versão do pacote Package.tt
Sempre que você adicionar ou alterar um comando, atualizar o version parâmetro da ProvideMenuResourceAttribute que é aplicado à classe de pacote antes de liberar a nova versão da sua linguagem específica de domínio.
Como a classe package é definida em um arquivo gerado, atualize o atributo no arquivo de modelo de texto que gera o arquivo Package.cs.
Para atualizar o arquivo Package.tt
Em Solution Explorer, no DslPackage projeto, o GeneratedCode pasta, abra o arquivo Package.tt.
Localize o ProvideMenuResource atributo.
Incremento de version parâmetro do atributo, que é o segundo parâmetro.Se desejar, você pode escrever o nome do parâmetro explicitamente para lembrá-lo de sua finalidade.Por exemplo:
[VSShell::ProvideMenuResource("1000.ctmenu", version: 2 )]
Definir o comportamento do comando
O DSL já tem alguns comandos que são implementados em uma classe parcial declarado em DslPackage\GeneratedCode\CommandSet.cs.Para adicionar novos comandos, você deve estender essa classe, criando um novo arquivo que contém uma declaração parcial da mesma classe.O nome da classe é normalmente <YourDslName>CommandSet.Ele é útil começar verificando o nome da classe e inspeção de seu conteúdo.
O comando conjunto classe é derivada de CommandSet.
Estender a classe CommandSet
No Solution Explorer, no projeto DslPackage, abra a pasta GeneratedCode e procure em CommandSet.tt e abrir seu arquivo gerado CommandSet.cs.Observe o espaço para nome e o nome da primeira classe que é definido ali.Por exemplo, você pode ver:
namespace Company.Language1
{ ... internal partial class Language1CommandSet : ...
Na DslPackage, crie uma pasta chamada código personalizado.Nesta pasta, crie um novo arquivo de classe chamado CommandSet.cs.
No novo arquivo, escreva uma declaração parcial que tenha o mesmo namespace e nome da classe parcial gerada.Por exemplo:
namespace Company.Language1 /* Make sure this is correct */
{ internal partial class Language1CommandSet { ...
Nota se você usou o modelo de classe para criar o novo arquivo, você deve corrigir o espaço para nome e o nome da classe.
Estender a classe do comando Set
Normalmente o seu código de conjunto de comando precisará importar os namespaces a seguir:
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;
Ajuste o espaço para nome e o nome da classe para coincidir com aquelas em que o CommandSet.cs gerado:
namespace Company.Language1 /* Make sure this is correct */
{
// Same class as the generated class.
internal partial class Language1CommandSet
{
Você deve definir os dois métodos, uma para determinar quando o comando estará visível no menu de contexto e o outro para executar o comando.Esses métodos não são substituições; em vez disso, você registrá-los em uma lista de comandos.
Definir quando o comando estará visível
Para cada comando, defina um OnStatus... método que determina se o comando será exibido no menu e se ele será habilitado ou cinza.Definir o Visible e Enabled propriedades da MenuCommand, conforme mostrado no exemplo a seguir.Este método é chamado para construir o menu de atalho sempre que o usuário clica o diagrama, para que ele deve trabalhar rapidamente.
Neste exemplo, o comando é visível apenas quando o usuário tiver selecionado um tipo específico de forma e é habilitado somente quando pelo menos um dos elementos selecionados está em um estado particular.O exemplo é baseado no modelo DSL de diagrama de classe e ClassShape e ModelClass são tipos definidos em DSL:
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
} } } }
Os fragmentos a seguir são freqüentemente úteis nos métodos de OnStatus:
this.CurrentSelection.A forma que o usuário right-clicked sempre está incluída nesta lista.Se o usuário clica em uma parte em branco do diagrama, o diagrama é o único membro da lista.
this.IsDiagramSelected() - trueSe o usuário clicou em uma parte em branco do diagrama.
this.IsCurrentDiagramEmpty()
this.IsSingleSelection()-o usuário não tiver selecionado vários objetos
this.SingleSelection-a forma ou o diagrama que o usuário right-clicked
shape.ModelElement as MyLanguageElement-o elemento de modelo representado por uma forma.
Como diretriz geral, verifique o Visible propriedade dependem do que está selecionado e certificar o Enabled propriedade dependem do estado dos elementos selecionados.
Um método de OnStatus não deve alterar o estado do armazenamento.
Definir o que faz o comando
Para cada comando, defina um OnMenu... método que executa a ação necessária quando o usuário clica no comando de menu.
Se você fizer alterações a elementos de modelo, você deve fazê-lo dentro de uma transação.Para obter mais informações, consulte Como: modificar um comando de Menu padrão em um idioma específico do domínio.
Neste exemplo, ClassShape, ModelClass, e Comment são tipos definidos em DSL, o que é derivado do modelo de DSL de diagrama de classe.
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!
}
}
Para obter mais informações sobre como navegar para cada objeto no modelo e sobre como criar objetos e vínculos, consulte Como: modificar um comando de Menu padrão em um idioma específico do domínio.
O comando register
Repita as declarações dos valores GUID e ID que você fez na seção símbolos de CommandSet.vsct em C#:
private Guid guidCustomMenuCmdSet =
new Guid("00000000-0000-0000-0000-000000000000");
private const int grpidMyMenuGroup = 0x01001;
private const int cmdidMyContextMenuCommand = 1;
Use o mesmo valor GUID, conforme você inseriu na Commands.vsct.
Observação |
---|
Se você alterar a seção símbolos do arquivo VSCT, você também deve alterar essas declarações para corresponder.Você também deve incrementar o número de versão no Package.tt |
Registre seus comandos de menu como parte deste conjunto de comando.GetMenuCommands()é chamado uma vez quando o diagrama for inicializado:
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;
}
O comando de teste.
Compile e execute o DSL em uma instância experimental de Visual Studio.O comando deverá aparecer no menu de atalho nas situações em que você especificou.
Como utilizar o comando
Sobre o Solution Explorer barra de ferramentas, clique em Transformar todos os modelos de.
Pressione F5 para recriar a solução e iniciar a depuração de linguagem específica de domínio na compilação experimental.
Na compilação experimental, abra um diagrama de exemplo.
Clique com o botão direito diversos itens no diagrama para verificar se o comando é corretamente habilitado ou desabilitado e adequadamente mostrado ou oculto, dependendo do item selecionado.
Solução de problemas
Comando não aparecer no menu:
O comando será exibido apenas na depuração de instâncias de Visual Studio, até que você instale o pacote DSL.Para obter mais informações, consulte Implantação de soluções de linguagem específica do domínio.
Certifique-se de que o seu exemplo experimental tem a extensão de nome de arquivo correto para essa DSL.Para verificar a extensão de nome de arquivo, abra o DslDefinition.dsl na instância principal do Visual Studio.Em seguida, no Explorer DSL, botão direito do mouse no nó do Editor e, em seguida, clique em Propriedades.Na janela Properties, examine a propriedade de ExtensãoDeArquivo.
Você incrementar o número de versão do pacote?
Defina um ponto de interrupção no início do seu método de OnStatus.Ele deve interromper a quando você com o botão direito sobre qualquer parte do diagrama.
Não é chamado de método de OnStatus:
Verifique se os GUIDs e IDs no seu código de CommandSet correspondem na seção símbolos de Commands.vsct.
Commands.vsct, certifique-se de que o GUID e ID em cada nó pai identificam pai grupo correto.
Em um prompt de comando Visual Studio, digite devenv /rootsuffix exp /setup.Em seguida, reinicie a instância de depuração do Visual Studio.
Percorra o método OnStatus para verificar esse comando.Visível e o comando.Ativado estiver definido como true.
O texto do menu errado é exibido ou comando é exibido no lugar errado:
Certifique-se de que a combinação do GUID e ID é exclusiva para este comando.
Certifique-se de que você desinstalou com versões anteriores do pacote.
Consulte também
Conceitos
Como: modificar um comando de Menu padrão em um idioma específico do domínio
Outros recursos
Escrever código para personalizar uma linguagem específica de domínio