Compartilhar via


Como: Definir um comando de Menu em um diagrama de modelagem

Em Visual Studio Ultimate, você pode definir itens de menu adicionais que aparecem quando o usuário clica um diagrama UML. Você pode controlar se o comando de menu aparece e é ativado quando o usuário clica a qualquer elemento no diagrama, e você pode escrever código que é executado quando o usuário seleciona o item de menu. Você pode empacotar essas extensões em um Visual Studio a extensão de integração (VSIX) e distribuí-lo a outros Visual Studio Ultimate os usuários.

Requisitos

Definindo o comando de menu

Para criar um comando de menu para um designer UML, você deve criar uma classe que define o comportamento do comando e incorporar a classe em um Visual Studio integração extensão (VSIX). O VSIX atua como um recipiente que pode instalar o comando. Há dois métodos alternativos de definição de um comando de menu:

  • Crie um comando de menu no seu próprio VSIX usando um modelo de projeto. Este é o método mais rápido. Usá-lo se não desejar combinar os comandos de menu com outros tipos de extensão como, por exemplo, as extensões de validação, itens de caixa de ferramentas personalizado ou manipuladores de gesto.

  • Crie projetos VSIX e o comando de menu separado. Use este método se você deseja combinar vários tipos de extensão para o mesmo VSIX. Por exemplo, se o comando de menu espera o modelo para observar as restrições específicas, você pode incorporá-lo no mesmo VSIX como um método de validação.

Para criar um comando de menu no seu próprio VSIX

  1. No Novo projeto caixa de diálogo, em Projetos de modelagem, selecione Comando extensão.

  2. Abrir o .cs de arquivos no novo projeto e modificar o CommandExtension classe para implementar o comando.

    Para obter mais informações, consulte Implementando o comando de Menu.

  3. Você pode adicionar comandos adicionais a este projeto definindo novas classes.

  4. Teste o comando de menu pressionando F5. Para obter mais informações, consulte a execução do comando de Menu.

  5. Instalar o comando de menu em outro computador, copiando o arquivo bin\*\*.vsix que é criado pelo projeto. Para obter mais informações, consulte o comando de Menu de instalação.

Para criar um comando de menu separado em um projeto DLL (biblioteca) de classe

  1. Crie um projeto de biblioteca de classe, em uma nova Visual Studio solução, ou em uma solução existente.

    1. No menu File, aponte para New e clique Project.

    2. Em Modelos instalados, clique em C# Visual ou Visual Basic. Na coluna do meio, clique em Biblioteca de classe.

    3. Definir solução para indicar se você deseja criar uma nova solução ou para adicionar um componente a uma solução VSIX que você já tiver aberto.

    4. Definir o projeto de nome e local e clique em OK.

  2. Adicione as seguintes referências ao seu projeto.

    Referência

    O que isso permite que você faça

    System.ComponentModel.Composition

    Definir componentes usando Managed Extensibility Framework (mef).

    Microsoft.VisualStudio.UML.interfaces

    Ler e alterar as propriedades de elementos de modelo.

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Criar elementos de modelo, modificar formas em diagramas.

    Microsoft.VisualStudio.Modeling.SDK.10.0

    Defina manipuladores de eventos do modelo.

    Encapsule a série de alterações ao seu modelo. Para obter mais informações, consulte Como: Atualizações do modelo de link usando transações.

    Microsoft.VisualStudio.Modeling.SDK.Diagrams.10.0

    (nem sempre é necessário)

    Elementos de diagrama adicional de acesso para os manipuladores de gesto.

    Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer

    Necessário apenas para os comandos em diagramas de camada. Para obter mais informações, consulte Criando extensões para diagramas de camada.

    Defina os comandos em um diagrama de camada.

  3. Adicionar um arquivo de classe ao projeto e definir seu conteúdo para o código a seguir.

    ObservaçãoObservação

    Alterar o espaço para nome, nome da classe e o valor retornado por Text a sua preferência.

    using System.ComponentModel.Composition;   
    using System.Linq;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
    using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
    using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
    using Microsoft.VisualStudio.Uml.Classes; 
        // ADD other UML namespaces if required
    
    namespace UMLmenu1 // CHANGE
    {
      // DELETE any of these attributes if the command
      // should not appear in some types of diagram.
      [ClassDesignerExtension]
      [ActivityDesignerExtension]
      [ComponentDesignerExtension]
      [SequenceDesignerExtension]
      [UseCaseDesignerExtension]
      // [LayerDesignerExtension] // if you have installed Feature Pack 1
    
      // All menu commands must export ICommandExtension:
      [Export (typeof(ICommandExtension))]
      // CHANGE class name
      public class Menu1 : ICommandExtension
      {
        [Import]
        public IDiagramContext DiagramContext { get; set; }
    
        public void QueryStatus(IMenuCommand command)
        { // Set command.Visible or command.Enabled to false
          // to disable the menu command.
          command.Visible = command.Enabled = true;
        }
    
        public string Text
        {
          get { return "MENU COMMAND LABEL"; }
        }
    
        public void Execute(IMenuCommand command)
        {
          // A selection of starting points:
          IDiagram diagram = this.DiagramContext.CurrentDiagram;
          foreach (IShape<IElement> shape in diagram.GetSelectedShapes<IElement>())
          { IElement element = shape.Element; }
          IModelStore modelStore = diagram.ModelStore;
          IModel model = modelStore.Root;
          foreach (IElement element in modelStore.AllInstances<IClass>()) 
          { }
        }
      }
    }
    

    Para obter mais informações sobre o que colocar nos métodos, consulte Implementando o comando de Menu.

Você deve adicionar o comando de menu para um projeto VSIX, que atua como um recipiente para o comando de instalação. Se desejar, você pode incluir outros componentes no mesmo VSIX.

Para adicionar um comando de menu separado para um projeto VSIX

  1. Esse procedimento não é necessário se você tiver criado o comando de menu com seu próprio VSIX.

  2. Crie um projeto VSIX, a menos que sua solução já tenha uma.

    1. Em Solution Explorer, a solução com o botão direito, aponte para Adde em seguida, clique em Novo projeto.

    2. Em Modelos instalados, expanda Visual C# ou Visual Basic, em seguida, clique em extensibilidade. Na coluna do meio, clique em O projeto de VSIX.

  3. Defina o projeto VSIX como o projeto de inicialização da solução.

    No Solution Explorer, clique com o botão direito no projeto VSIX e clique em Set as StartUp project.

  4. Em source.extension.vsixmanifest, em conteúdo, adicione o projeto de biblioteca de classe como um componente de MEF.

    1. Abrirsource.extension.vsixmanifest

    2. Clique em Adicionar conteúdo.

    3. Em Selecione um tipo de conteúdo, selecione MEF componente.

    4. Em Selecionar uma fonte de, clique em projeto e selecione o nome do seu projeto de biblioteca de classe.

  5. Clique em Selecione edições e selecione o Visual Studio edições você deseja que sua extensão a ser executada.

  6. Defina o nome e os campos descritivos do VSIX. Salve o arquivo.

Implementando o comando de Menu

A classe de comando de menu implementa os métodos necessários para ICommandExtension.

string Text { get; }

Retorne o rótulo do seu item de menu.

void QueryStatus(IMenuCommand command);

Chamado quando o usuário clica com o botão direito no diagrama.

Este método não deve alterar o modelo.

Use DiagramContext.CurrentDiagram.SelectedShapes para determinar se deseja que o comando deve aparecer e ser ativado.

Defina:

  • command.Visiblepara true se o comando deve aparecer no menu quando o usuário clica com o botão direito no diagrama

  • command.Enabledpara true se o usuário pode clicar no comando no menu

  • command.TextPara definir o rótulo de menu dinamicamente

void Execute (IMenuCommand command);

Chamado quando o usuário clica o item de menu, se ele estiver visível e ativado.

 

Acessando o modelo de código

Incluindo a declaração a seguir na sua classe de comando de menu:

[Import] public IDiagramContext DiagramContext { get; set; }

...

A declaração de IDiagramContext lhe permite escrever código em seus métodos que acessa o diagrama, a seleção atual e o modelo:

IDiagram diagram = this.DiagramContext.CurrentDiagram;
foreach (IShape<IElement> shape in diagram.GetSelectedShapes<IElement>())
{ IElement element = shape.Element; ... }
IModelStore modelStore = diagram.ModelStore;
IModel model = modelStore.Root;
foreach (IElement element in modelStore.AllInstances<IUseCase>()) {...}

Os elementos de modelo UML estarão disponíveis por meio da API. Da seleção atual ou da raiz do modelo, você pode acessar todos os outros elementos. Para obter mais informações, consulte Como: Navegue de modelo UML e Programação com a API de UML.

Se você estiver lidando com um diagrama de seqüência, consulte também Como: Editar os diagramas de seqüência usando a API de UML.

A API também permite que você alterar as propriedades dos elementos, excluir elementos e relações e criar relações e novos elementos.

Por padrão, cada alteração feita no seu método de execução será executada em uma transação separada. O usuário será capaz de desfazer a cada alteração separadamente. Se você deseja agrupar as alterações em uma única transação, use um ILinkedUndoTransaction conforme descrito em Como: Atualizações do modelo de link usando transações.

Use o segmento de interface do usuário para atualizações

Em alguns casos pode ser útil fazer atualizações com o modelo de um segmento de plano de fundo. Por exemplo, se o seu comando carrega dados de um recurso lento, você pode executar o carregamento em um thread de brackground para que o usuário possa ver as alterações enquanto eles estão em andamento e cancelar a operação, se for necessário.

No entanto, você deve conhecer o armazenamento de modelo não é thread-safe. Você sempre deve usar thread da interface (UI) do usuário para fazer atualizações e se é possível impedir o usuário fazer edições, enquanto a operação de plano de fundo está em andamento. Para um exemplo, consulte Como: Atualizar um modelo UML a partir de um Thread de plano de fundo.

Executar o comando de Menu

Para fins de teste, execute o comando no modo de depuração.

Para testar o comando de menu

  1. Pressione F5, ou de Debug menu, clique em Start Debugging.

    Uma instância experimental do Visual Studio é iniciado.

    Solucionando problemas de: Se uma nova Visual Studio não iniciado:

    • Se você tiver mais de um projeto, certifique-se de que o projeto VSIX é definido como o projeto de inicialização da solução.

    • No Solution Explorer, clique com o botão direito na inicialização ou somente projeto e clique em Propriedades. No editor de propriedades do projeto, clique na Debug guia. Certifique-se de que a seqüência de caracteres de Start external program campo é o caminho completo do Visual Studio, normalmente:

      10.0\Common7\IDE\devenv.exe do c:\Arquivos de Programas\Microsoft Visual Studio

  2. No experimental Visual Studio, abra ou crie um projeto de modelagem e abrir ou criar um diagrama de modelagem. Use um diagrama que pertence a um dos tipos listados nos atributos de sua classe de comando de menu.

  3. Com o botão direito em qualquer lugar no diagrama. O comando deverá aparecer no menu.

    Solucionando problemas de: Se o comando não aparecer no menu, certifique-se de que:

    • O projeto do comando de menu é listado como um componente MEF a conteúdo Listar no source.extensions.manifest no projeto VSIX.

    • Os parâmetros da Import e Export atributos são válidos.

    • O QueryStatus método não está definindo a command.Enabled or Visible fields to false.

    • O tipo de diagrama de modelo que você está usando (classe UML, seqüência e assim por diante) é listado como um dos atributos de classe de comando de menu [ClassDesignerExtension], [SequenceDesignerExtension] e assim por diante.

Instalar e desinstalar uma extensão.

Você pode instalar um Visual Studio extensão em seu próprio computador e em outros computadores.

Para instalar uma extensão.

  1. No seu computador, localize o .vsix arquivo que foi criado pelo seu projeto VSIX.

    1. Em Solution Explorer, o botão direito do mouse no projeto VSIX e em Abrir a pasta no Windows Explorer.

    2. Localize o arquivo bin\*\YourProject.vsix

  2. Cópia de .vsix o arquivo para o computador de destino no qual você deseja instalar a extensão. Isso pode ser o seu próprio computador ou outro.

    O computador de destino deve ter uma das edições do Visual Studio que você especificou na source.extension.vsixmanifest.

  3. No computador de destino, clique duas vezes o .vsix arquivo.

    Instalador de extensão de Visual Studio abre e instala a extensão.

  4. Iniciar ou reiniciar Visual Studio.

Para desinstalar uma extensão.

  1. Sobre o Ferramentas menu, clique em Extension Manager.

  2. Expanda as extensões instaladas.

  3. Selecione a extensão e clique em desinstalar.

Raramente, uma extensão com defeito não consegue carregar e cria um relatório na janela de erros, mas não aparece no Gerenciador de extensão. Nesse caso, você pode remover a extensão, excluindo o arquivo:

% LocalAppData %\Local\Microsoft\VisualStudio\10.0\Extensions

Exemplo

O exemplo a seguir mostra o código para um comando de menu será interchange os nomes dos dois elementos em um diagrama de classe. Esse código deve ser construído um Visual Studio o projeto de extensão e instalado conforme descrito nas seções anteriores.

using System.Collections.Generic; // for IEnumerable
using System.ComponentModel.Composition;
  // for [Import], [Export]
using System.Linq; // for IEnumerable extensions
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
  // for IDiagramContext
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
  // for designer extension attributes
using Microsoft.VisualStudio.Modeling.Diagrams;
  // for ShapeElement
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
  // for IGestureExtension, ICommandExtension, ILinkedUndoContext
using Microsoft.VisualStudio.Uml.Classes;
  // for class diagrams, packages

/// <summary>
/// Extension to swap names of classes in a class diagram.
/// </summary>
namespace SwapClassNames
{
  // Declare the class as an MEF component:
  [Export(typeof(ICommandExtension))]
  [ClassDesignerExtension]
  // Add more ExportMetadata attributes to make
  // the command appear on diagrams of other types.
  public class NameSwapper : ICommandExtension
  {
  // MEF required interfaces:
  [Import]
  public IDiagramContext Context { get; set; }
  [Import]
  public ILinkedUndoContext LinkedUndoContext { get; set; }

  /// <summary>
  /// Swap the names of the currently selected elements.
  /// </summary>
  /// <param name="command"></param>
  public void Execute(IMenuCommand command)
  {
    // Get selected shapes that are IClassifiers -
    // IClasses, IInterfaces, IEnumerators.
    var selectedShapes = Context.CurrentDiagram
     .GetSelectedShapes<IClassifier>();
    if (selectedShapes.Count() < 2) return;

    // Get model elements displayed by shapes.
    IClassifier firstElement = selectedShapes.First().Element;
    IClassifier lastElement = selectedShapes.Last().Element;

    // Do the swap in a transaction so that user
    // cannot undo one change without the other.
    using (ILinkedUndoTransaction transaction =
    LinkedUndoContext.BeginTransaction("Swap names"))
    {
    string firstName = firstElement.Name;
    firstElement.Name = lastElement.Name;
    lastElement.Name = firstName;
    transaction.Commit();
    }
  }

  /// <summary>
  /// Called by Visual Studio to determine whether
  /// menu item should be visible and enabled.
  /// </summary>
  public void QueryStatus(IMenuCommand command)
  { 
    int selectedClassifiers = Context.CurrentDiagram
     .GetSelectedShapes<IClassifier>().Count();
    command.Visible = selectedClassifiers > 0;
    command.Enabled = selectedClassifiers == 2;
  }

  /// <summary>
  /// Name of the menu command.
  /// </summary>
  public string Text
  {
    get { return "Swap Names"; }
  }
  }

}

Consulte também

Conceitos

Diagramas e modelos UML estendendo

Como: Definir restrições de validação dos modelos UML

Programação com a API de UML

Outros recursos

Como: Definir e instalar uma extensão de modelagem

Como: Definir uma queda e clique duas vezes o manipulador de um diagrama de modelagem

Como: Definir um Item da caixa de ferramentas de modelagem de personalizado

Como: Editar os diagramas de seqüência usando a API de UML