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

Em Visual Studio Ultimate, você pode definir os comandos que são executados quando o usuário clica duas vezes ou arrasta itens em um diagrama UML. 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.

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

Requisitos

Criar um manipulador de gesto

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

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

  • Crie o manipulador de gesto separado e projetos VSIX. Use este método se você deseja combinar vários tipos de extensão para o mesmo VSIX. Por exemplo, se o seu manipulador de gesto 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 manipulador de gesto no seu próprio VSIX

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

  2. Abrir o .cs de arquivos no novo projeto e modificar o GestureExtension classe para implementar seu manipulador de gesto.

    Para obter mais informações, consulte a implementação do manipulador de gesto.

  3. Teste o manipulador de gesto, pressionando F5. Para obter mais informações, consulte executar o manipulador de gesto.

  4. Instalar o manipulador de gesto em outro computador, copiando o arquivo bin\*\*.vsix que é criado pelo projeto. Para obter mais informações, consulte instalação do manipulador do gesto de.

Para criar o projeto de biblioteca de classe (DLL) para o manipulador de gesto

  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, em seguida, 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.

    Microsoft.VisualStudio.Modeling.Sdk.10.0

    Microsoft.VisualStudio.Modeling.Sdk.Diagrams.10.0

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Microsoft.VisualStudio.Uml.Interfaces

    System.ComponentModel.Composition

    System.Windows.Forms

    Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer– É necessário somente se você estiver estendendo os diagramas de camada. Para obter mais informações, consulte Criando extensões para diagramas de camada.

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

    ObservaçãoObservação

    Altere o nome do namespace e classe de acordo com a 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 colocar nos métodos, consulte a implementação do manipulador de gesto.

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 manipulador de gesto separada a 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 de manipulador do gesto 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 de manipulador de gesto.

  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.

Executar o manipulador de gesto

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

Para testar o manipulador de gesto

  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 classe de manipulador seu gesto.

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

  4. Arraste um elemento do Explorer de UML para o diagrama. O manipulador de arrastar deve ser chamado.

Solucionando problemas de: Se o manipulador de gesto não funciona, certifique-se de que:

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

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

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

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

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

O manipulador do gesto de implementação

Os métodos do manipulador de gesto

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

bool CanDragDrop (ShapeElement target, DiagramDragEventArgs dragEvent)

Retornar true para permitir que o elemento de origem referenciado na dragEvent a serem descartados no destino.

Este método não deve fazer alterações no modelo. Ele deve funcionar rapidamente, pois ele é usado para determinar o estado de seta, conforme o usuário move o mouse.

void OnDragDrop (ShapeElement target, DiagramDragEventArgs dragEvent)

Atualizar o modelo baseado no objeto de origem referenciado na dragEvente o destino.

Chamado quando o usuário solta o mouse depois de 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 só UML também uma ampla variedade de outros itens, como, por exemplo, arquivos, nós em um.NET class view, nós de arquitetura Explorer e assim por diante. O usuário pode arrastar qualquer um desses itens em um diagrama UML, desde que você escrever uma OnDragDrop método que possa decodificar o formulário serializado 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 no qual o usuário tiver arrastado algo.

    ShapeElementé uma classe de implementação que dá suporte a UML ferramentas de modelagem. Para reduzir o risco de colocar o modelo UML e os diagramas em um estado inconsistente, recomendamos que você não use os métodos dessa classe diretamente. Em vez disso, dispor o elemento em um IShapee use os métodos descritos no Como: Exibir um modelo em diagramas.

    • Para obter um IShape:

      IShape targetIShape = target.CreateIShape(target);
      
    • Para obter o elemento de modelo que é o destino de arrastar, ou clique duas vezes em operação:

      IElement target = targetIShape.Element;
      

      Você pode usar esta opção para um tipo mais específico do elemento.

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

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

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

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

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

    Se o objeto de origem é um elemento UML arrastado do Gerenciador de modelos UML ou de outro diagrama UML, consulte Como: Obter os elementos de modelo UML IDataObject.

Escrever o código dos métodos

Para obter mais informações sobre como escrever o 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 sobre o modelo em uma operação de arrastar, consulte Como: Obter os elementos de modelo UML IDataObject.

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.

Além de para os parâmetros dos métodos, também é possível declarar uma propriedade importada em sua classe que fornece acesso para o diagrama atual e o modelo.

[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 (IDiagram diagram in modelStore.Diagrams) {...}
foreach (IElement element in modelStore.AllInstances<IUseCase>) {...}

Para obter mais informações, consulte Como: Navegue de modelo UML.

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 como criar linhas de vida em um diagrama de seqüência, com base em que as partes e as portas de um componente, arrastado de um diagrama de componente.

Para testá-lo, pressione F5. Abre a uma instância experimental do Visual Studio. Neste exemplo, abrir um modelo UML e criar um componente em um diagrama de componente. Adicione a este componente algumas interfaces e partes do componente interno. Selecione as partes e interfaces. Em seguida, arraste as partes e as interfaces de um diagrama de seqüência. (Arrastar para o diagrama de seqüência do diagrama de componente até a guia para o diagrama de seqüência e, em seguida, down.) Uma linha de vida será exibida para cada interface e a parte.

Para obter mais informações sobre as interações de ligação aos diagramas de seqüência, consulte Como: Editar os 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 os elementos de modelo UML IDataObject.

Consulte também

Conceitos

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

Outros recursos

Como: Definir e instalar uma extensão de modelagem