Compartilhar via


Como: definir um manipulador de gesto em um diagrama de modelagem

No Visual Studio final, você pode definir os comandos que são executados quando o usuário clica duas vezes ou arrasta itens em um diagrama de UML.Você pode armazenar essas extensões em uma extensão de integração do Visual Studio (VSIX) e distribui-las para outros usuários finais do Visual Studio.

Se já há um comportamento interno para o tipo de diagrama e o tipo de elemento que você deseja arrastar, você não poderá adicionar a ou substituir esse comportamento.

Requisitos

Criando um manipulador do gesto

Para definir um tratador do gesto para um designer de UML, você deve criar uma classe que define o comportamento do manipulador do gesto, e inserir essa classe em uma extensão de integração do Visual Studio (VSIX).O VSIX atua como um recipiente que pode instalar o manipulador.Há dois métodos alternativas de definir um tratador do gesto:

  • Crie um manipulador do gesto em seu próprio VSIX usando um modelo de projeto. Este é o método mais rápido.Use se você não desejar combinar o manipulador com outros tipos de extensão como extensões de validação, itens personalizados da caixa de ferramentas, ou comandos de menu.

  • Crie o manipulador separado do gesto e projetos de VSIX. Use este método se você desejar combinar vários tipos de extensão no mesmo VSIX.Por exemplo, se seu manipulador do gesto espera o modelo observe restrições específicas, você pode incorporar-lo no mesmo VSIX que um método de validação.

Para criar um manipulador do gesto em seu próprio VSIX

  1. Na caixa de diálogo Novo Projeto , em Modelando projetos, Extensão do gesto.

  2. Abra o arquivo de .cs no novo projeto e modificar a classe de GestureExtension para implementar seu manipulador do gesto.

    Para obter mais informações, consulte Implementando o manipulador do gesto.

  3. Testar o manipulador de ação pressionando F5.Para obter mais informações, consulte Executando o manipulador do gesto.

  4. Instalar o manipulador do gesto em outro computador copiar o arquivo bin\*\*.vsix que é compilado pelo seu projeto.Para obter mais informações, consulte Instalando o manipulador do gesto.

Aqui está o procedimento alternativo:

Para criar um projeto de biblioteca de classes separado (DLL) para o manipulador do gesto

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

    1. No menu de Arquivo , escolha Novo, Projeto.

    2. Em Modelos Instalados, expanda Visual C# ou Visual Basic, então a coluna do meio escolha Biblioteca de Classes.

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

    Microsoft.VisualStudio.Modeling.Sdk.11.0

    Microsoft.VisualStudio.Modeling.Sdk.Diagrams.11.0

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Microsoft.VisualStudio.Uml.Interfaces

    System.ComponentModel.Composition

    System.Windows.Forms

    Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer – você precisa isso somente se você estiver estendendo diagramas de camada.Para obter mais informações, consulte Estendendo os diagramas de camada.

  3. Adicione um arquivo de classe ao projeto e defina seu conteúdo código a seguir.

    ObservaçãoObservação

    Alterar o namespace e o nome da classe de acordo com sua preferência.

    using System.ComponentModel.Composition;
    using System.Linq;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.Modeling.Diagrams;
    using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement;
    using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
    using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
    using Microsoft.VisualStudio.Modeling;
    using Microsoft.VisualStudio.Uml.Classes;
    // ADD other UML namespaces if required
    
    namespace MyGestureHandler // CHANGE
    {
      // DELETE any of these attributes if the handler
      // should not work with some types of diagram.
      [ClassDesignerExtension]
      [ActivityDesignerExtension]
      [ComponentDesignerExtension]
      [SequenceDesignerExtension]
      [UseCaseDesignerExtension]
      // [LayerDesignerExtension]
    
      // Gesture handlers must export IGestureExtension:
      [Export(typeof(IGestureExtension))]
      // CHANGE class name
      public class MyGesture1 : IGestureExtension
      {
        [Import]
        public IDiagramContext DiagramContext { get; set; }
    
        /// <summary>
        /// Called when the user double-clicks on the diagram
        /// </summary>
        /// <param name="targetElement"></param>
        /// <param name="diagramPointEventArgs"></param>
        public void OnDoubleClick(ShapeElement targetElement, DiagramPointEventArgs diagramPointEventArgs)
        {
          // CHANGE THIS CODE FOR YOUR APPLICATION.
    
          // Get the target shape, if any. Null if the target is the diagram.
          IShape targetIShape = targetElement.CreateIShape();
    
          // Do something...
        }
    
        /// <summary>
        /// Called repeatedly when the user drags from anywhere on the screen.
        /// Return value should indicate whether a drop here is allowed.
        /// </summary>
        /// <param name="targetMergeElement">References the element to be dropped on.</param>
        /// <param name="diagramDragEventArgs">References the element to be dropped.</param>
        /// <returns></returns>
        public bool CanDragDrop(ShapeElement targetMergeElement, DiagramDragEventArgs diagramDragEventArgs)
        {
          // CHANGE THIS CODE FOR YOUR APPLICATION.
    
          // Get the target element, if any. Null if the target is the diagram.
          IShape targetIShape = targetMergeElement.CreateIShape();
    
          // This example allows drag of any UML elements.
          return GetModelElementsFromDragEvent(diagramDragEventArgs).Count() > 0;
        }
    
    
        /// <summary>
        /// Execute the action to be performed on the drop.
        /// </summary>
        /// <param name="targetDropElement"></param>
        /// <param name="diagramDragEventArgs"></param>
        public void OnDragDrop(ShapeElement targetDropElement, DiagramDragEventArgs diagramDragEventArgs)
        {
          // CHANGE THIS CODE FOR YOUR APPLICATION.
        }
    
        /// <summary>
        /// Retrieves UML IElements from drag arguments.
        /// Works for drags from UML diagrams.
        /// </summary>
        private IEnumerable<IElement> GetModelElementsFromDragEvent
                (DiagramDragEventArgs dragEvent)
        {
          //ElementGroupPrototype is the container for
          //dragged and copied elements and toolbox items.
          ElementGroupPrototype prototype =
             dragEvent.Data.
             GetData(typeof(ElementGroupPrototype))
                  as ElementGroupPrototype;
          // Locate the originals in the implementation store.
          IElementDirectory implementationDirectory =
             dragEvent.DiagramClientView.Diagram.Store.ElementDirectory;
    
          return prototype.ProtoElements.Select(
            prototypeElement =>
            {
              ModelElement element = implementationDirectory
                .FindElement(prototypeElement.ElementId);
              ShapeElement shapeElement = element as ShapeElement;
              if (shapeElement != null)
              {
                // Dragged from a diagram.
                return shapeElement.ModelElement as IElement;
              }
              else
              {
                // Dragged from UML Model Explorer.
                return element as IElement;
              }
            });
        }
    
      }
    }
    

    Para obter mais informações sobre o que a colocar os métodos, consulte Implementando o manipulador do gesto.

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

Para adicionar um manipulador separado do gesto a um projeto VSIX

  1. Você não precisa este procedimento se você criou o manipulador do gesto com seu próprio VSIX.

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

    1. Em Gerenciador de Soluções, no menu de atalho de solução, escolha Adicionar, Novo Projeto.

    2. Em Modelos Instalados, expanda Visual C# ou Visual Basic, então selecione Extensibilidade.Na coluna do meio, escolha VSIX Projeto.

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

    • No solution Explorer, no menu de atalho do projeto de VSIX, escolha Definir como projeto de inicialização.
  4. Em source.extension.vsixmanifest, adicione o projeto de biblioteca de classe de manipulador do gesto como um componente de MEF:

    1. Na guia de Metadados , definir um nome para o VSIX.

    2. Na guia de Instalar destinos , defina o Visual Studio final e superior como alvo.

    3. Na guia de Ativos , escolha Novoe, na caixa de diálogo, conjunto:

      Tipo = Componente de MEF

      Origem = Um projeto na solução atual

      Projeto = Seu projeto de biblioteca de classe

Executando o manipulador do gesto

Para fins de teste, execute o manipulador do gesto no modo de depuração.

Para testar o manipulador do gesto

  1. Pressione F5, ou no menu de Depurar , clique Iniciar Depuração.

    Uma instância de avaliação de começa de Visual Studio .

    Solução de Problemas: Se novo Visual Studio não começa:

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

    • No solution Explorer, no menu de atalho de inicialização ou apenas de projeto, escolha propriedades.No editor de propriedades de projeto, escolha o guia de Depurar .Certifique-se de que a cadeia de caracteres no campo de Iniciar programa externo é o nome do caminho completo de Visual Studio, normalmente:

      c:\program files\microsoft Visual Studio 11,0 \ Common7 \ IDE \ devenv.exe

  2. Em Visual Studiode avaliação, abra ou crie um projeto e modelagem, abra ou crie um diagrama modelando.Use um diagrama que pertence a um dos tipos listados nos atributos de sua classe de manipulador do gesto.

  3. Clique duas vezes em qualquer lugar no diagrama.O clique duas vezes no manipulador deve ser chamado.

  4. Arraste um elemento de UML Explorer no diagrama.O manipulador de arrastar deve ser chamado.

Solução de Problemas: Se o manipulador do gesto não funciona, certifique-se que:

  • O projeto do manipulador do gesto é listado como um componente de MEF na guia de Ativos em source.extensions.manifest no projeto de VSIX.

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

  • O método de CanDragDrop não está retornando false.

  • O tipo de modelo diagrama você está usando (classe, sequência de UML, e assim por diante) é listado como um dos atributos de manipulação de classe do gesto [ClassDesignerExtension,] [] SequenceDesignerExtension que e assim por diante.

  • Não há nenhuma funcionalidade interna já definida para esse tipo de destino e de elemento solto.

Implementando o manipulador do gesto

Ee534033.collapse_all(pt-br,VS.110).gifOs métodos do manipulador do gesto

A classe manipulador do gesto implementa e exportar IGestureExtension.Os métodos que você precisa definir são:

bool CanDragDrop (ShapeElement target, DiagramDragEventArgs dragEvent)

true de retorno para permitir o elemento de origem referenciado em dragEvent a ser solto neste destino.

Este método não deve fazer alterações no modelo.Deve trabalhar rapidamente, porque é usado para determinar o estado da seta quando o usuário move o mouse.

void OnDragDrop (ShapeElement target, DiagramDragEventArgs dragEvent)

Atualizar o modelo baseado no objeto de origem referenciado em dragEvent, e o destino.

Chamado quando o usuário liberar o mouse após arrastar.

void OnDoubleClick (ShapeElement target, DiagramPointEventArgs pointEvent)

target é a forma que o usuário clicou duas vezes.

Você pode escrever manipuladores que podem aceitar não apenas UML também uma ampla variedade de outros itens, como arquivos, nós no modo de exibição de uma classe .NET, nós do gerenciador de arquitetura, e assim por diante.O usuário pode arrastar qualquer um desses itens em um diagrama de UML, desde que você escreve um método de OnDragDrop que possa decodificar o formulário serializada de itens.Os métodos de decodificação variam de um tipo de item para outro.

Os parâmetros desses métodos são:

  • ShapeElement target.A forma ou o diagrama em que o usuário arrastou algo.

    ShapeElement é uma classe na implementação que é a base de UML que modela ferramentas.Para reduzir o risco de colocar o modelo e os diagramas de UML em um estado inconsistente, recomendamos que você não use os métodos dessa classe diretamente.Em vez disso, coloque o elemento em IShapeem seguida, use os métodos descritos em Como: exibir um modelo em diagramas.

    • Para obter IShape:

      IShape targetIShape = target.CreateIShape(target);
      
    • Para obter o elemento modelo que é definido pelo arrastar ou clique duas vezes na operação:

      IElement target = targetIShape.Element;
      

      Você pode converter a esse tipo mais específico de elemento.

    • Para obter o modelo de UML armazenar que contém o modelo de UML:

      IModelStore modelStore = 
        targetIShape.Element.GetModelStore(); 
      
    • Para obter acesso ao host e o provedor de serviços:

      target.Store.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE
      
  • DiagramDragEventArgs eventArgs.Este parâmetro leva o formulário serializada do objeto de origem de uma operação de arrastar:

    System.Windows.Forms.IDataObject data = eventArgs.Data;  
    

    Você pode arrastar elementos de vários tipos diferentes em um diagrama, as partes diferentes de Visual Studio, ou de área de trabalho do Windows.Os diferentes tipos de elemento são codificados em diferentes maneiras em IDataObject.Para extrair os elementos dele, consulte a documentação para o tipo apropriado de objeto.

    Se seu objeto fonte é um elemento de UML arrastado do modelo de UML Explorer ou outro diagrama de UML, consulte Como: obter elementos de modelo UML do IDataObject.

Ee534033.collapse_all(pt-br,VS.110).gifEscrevendo código dos métodos

Para obter mais informações sobre a escrever código para ler e atualizar o modelo, consulte Programação com a API de UML.

Para obter informações sobre como acessar informações modelo em uma operação de arrastar, consulte Como: obter elementos de modelo UML do IDataObject.

Se você está tratando um diagrama de sequência, consulte também Como: Editar diagramas de seqüência usando a API de UML.

Além dos parâmetros dos métodos, você pode também declarar uma propriedade importado na sua classe que fornece acesso ao diagrama e o modelo atual.

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

A declaração de IDiagramContext permite que você escreva 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 (IDiagram diagram in modelStore.Diagrams) {...}
foreach (IElement element in modelStore.AllInstances<IUseCase>) {...}

Para obter mais informações, consulte Como: navegar o modelo UML.

Instalando e desinstalar uma extensão

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

Para instalar uma extensão

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

    1. Em Gerenciador de Soluções, no menu de atalho do projeto de VSIX, escolha Abrir pasta no Windows Explorer.

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

  2. Copiar o arquivo de .vsix para o computador de destino que 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 de Visual Studio que você especificou em source.extension.vsixmanifest.

  3. No computador de destino, abra o arquivo de .vsix .

    Instalador de extensão do Visual Studio abre e instalar a extensão.

  4. Início ou reinicialização Visual Studio.

Para desinstalar uma extensão

  1. No menu de Ferramentas , escolha Gerenciador de Extensões.

  2. Expanda Extensões Instaladas.

  3. Selecione a extensão, escolha Desinstalar.

Raramente, uma extensão defeituosas não carrega e cria um relatório na janela de erro, mas não aparece no gerenciador de extensão.Nesse caso, você pode remover a extensão deletando o arquivo de:

%LocalAppData%\Local\Microsoft\VisualStudio\11.0\Extensions

Exemplo

O exemplo a seguir mostra como criar cordas de salvamento em um diagrama de sequência, com base nas partes e as portas de um componente, arrastadas de um diagrama componente.

Para testá-lo, pressione F5.Uma instância de avaliação do Visual Studio abre.Nesse caso, abra um modelo de UML e criar um componente em um diagrama componente.Adicione a este componente alguns interfaces e elementos internos.Selecione as interfaces e as partes.Arraste então interfaces e as partes em um diagrama de sequência.(A direita do diagrama componente até a guia para o diagrama de sequência, e então para baixo no diagrama de sequência.) Uma corda de salvamento será exibido para cada interface e parte.

Para obter mais informações sobre as interações de associação para diagramas de sequência, consulte Como: Editar diagramas de seqüência usando a API de UML.

using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement;
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.Uml.AuxiliaryConstructs;
using Microsoft.VisualStudio.Uml.Classes;
using Microsoft.VisualStudio.Uml.Interactions;
using Microsoft.VisualStudio.Uml.CompositeStructures;
using Microsoft.VisualStudio.Uml.Components;

/// <summary>
/// Creates lifelines from component ports and parts.
/// </summary>
[Export(typeof(IGestureExtension))]
[SequenceDesignerExtension]
public class CreateLifelinesFromComponentParts : IGestureExtension
{
  [Import]
  public IDiagramContext Context { get; set; }

  /// <summary>
  /// Called by the modeling framework when
  /// the user drops something on a target.
  /// </summary>
  /// <param name="target">The target shape or diagram </param>
  /// <param name="dragEvent">The item being dragged</param>
  public void OnDragDrop(ShapeElement target,
           DiagramDragEventArgs dragEvent)
  {
    ISequenceDiagram diagram = Context.CurrentDiagram
            as ISequenceDiagram;
    IInteraction interaction = diagram.Interaction;
    if (interaction == null)
    {
      // Sequence diagram is empty: create an interaction.
      interaction = diagram.ModelStore.Root.CreateInteraction();
      interaction.Name = Context.CurrentDiagram.Name;
      diagram.Bind(interaction);
    }
    foreach (IConnectableElement connectable in
       GetConnectablesFromDrag(dragEvent))
    {
      ILifeline lifeline = interaction.CreateLifeline();
      lifeline.Represents = connectable;
      lifeline.Name = connectable.Name;
    }
  }

  /// <summary>
  /// Called by the modeling framework to determine whether
  /// the user can drop something on a target.
  /// Must not change anything.
  /// </summary>
  /// <param name="target">The target shape or diagram</param>
  /// <param name="dragEvent">The item being dragged</param>
  /// <returns>true if this item can be dropped on this target</returns>
  public bool CanDragDrop(ShapeElement target,
           DiagramDragEventArgs dragEvent)
  {
    IEnumerable<IConnectableElement> connectables = GetConnectablesFromDrag(dragEvent);
    return connectables.Count() > 0;
  }

  ///<summary>
  /// Get dragged parts and ports of an IComponent.
  ///</summary>
  private IEnumerable<IConnectableElement>
    GetConnectablesFromDrag(DiagramDragEventArgs dragEvent)
  {
    foreach (IElement element in
      GetModelElementsFromDragEvent(dragEvent))
    {
      IConnectableElement part = element as IConnectableElement;
      if (part != null)
      {
        yield return part;
      }
    }
  }

  /// <summary>
  /// Retrieves UML IElements from drag arguments.
  /// Works for drags from UML diagrams.
  /// </summary>
  private IEnumerable<IElement> GetModelElementsFromDragEvent
          (DiagramDragEventArgs dragEvent)
  {
    //ElementGroupPrototype is the container for
    //dragged and copied elements and toolbox items.
    ElementGroupPrototype prototype =
       dragEvent.Data.
       GetData(typeof(ElementGroupPrototype))
            as ElementGroupPrototype;
    // Locate the originals in the implementation store.
    IElementDirectory implementationDirectory =
       dragEvent.DiagramClientView.Diagram.Store.ElementDirectory;

    return prototype.ProtoElements.Select(
      prototypeElement =>
      {
        ModelElement element = implementationDirectory
          .FindElement(prototypeElement.ElementId);
        ShapeElement shapeElement = element as ShapeElement;
        if (shapeElement != null)
        {
          // Dragged from a diagram.
          return shapeElement.ModelElement as IElement;
        }
        else
        {
          // Dragged from UML Model Explorer.
          return element as IElement;
        }
      });
  }

  public void OnDoubleClick(ShapeElement targetElement, DiagramPointEventArgs diagramPointEventArgs)
  {
  }
}

O código de GetModelElementsFromDragEvent() é descrito em Como: obter elementos de modelo UML do IDataObject.

Consulte também

Conceitos

Como: definir e instalar uma extensão de modelagem

Diagramas e modelos UML estendendo

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

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

Programação com a API de UML