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

Uma interação é uma seqüência de mensagens entre um conjunto de linhas de vida. Uma interação é exibida em um diagrama de seqüência.

Para obter detalhes completos da API, consulte Microsoft.VisualStudio.Uml.Interactions.

Para obter uma introdução mais geral para escrever os comandos e manipuladores de gesto para diagramas UML, consulte Como: Definir um comando de Menu em um diagrama de modelagem.

Código básico

Importações de namespace

Você deve incluir o seguinte using instruções:

using Microsoft.VisualStudio.Uml.Classes;
   // for basic UML types such as IPackage
using Microsoft.VisualStudio.Uml.Interactions;
   // for interaction types
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
   // to create elements and use additional functions

Se você estiver criando comandos de menu e manipuladores de gesto, também será necessário:

using System.ComponentModel.Composition; 
   // for Import and Export
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
   // for ICommandExtension
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
   // for diagrams and context

Para obter mais informações, consulte Como: Definir um comando de Menu em um diagrama de modelagem.

Obtendo o contexto.

Se você estiver editando uma interação como parte de um manipulador de comando ou o gesto em um diagrama de seqüência, você pode obter uma referência ao contexto. Por exemplo:

    [SequenceDesignerExtension]
    [Export(typeof(ICommandExtension))]  
    public class MySequenceDiagramCommand : ICommandExtension
    {
        [Import]
        public IDiagramContext Context { get; set; }
        public void QueryStatus (IMenuCommand command)
        {
          ISequenceDiagram sequenceDiagram = 
              Context.CurrentDiagram as ISequenceDiagram;
             ...

Gerado e diagramas de seqüência UML

Há dois tipos de diagramas de seqüência: aqueles que são criados manualmente em um projeto de modelagem UML e aqueles que são gerados a partir do código de programa. Você pode usar o UmlMode propriedade para descobrir que tipo de diagrama de seqüência que você estiver trabalhando com.

Por exemplo, se você deseja tornar um comando de menu só é visível em diagramas de seqüência UML, em seguida, a QueryStatus() método poderia incluir a instrução a seguir:

    command.Enabled = command.Visible = 
          sequenceDiagram != null && sequenceDiagram.UmlMode;

Em uma seqüência gerada diagrama, as linhas de vida de mensagens e outros elementos são da mesma em um diagrama de seqüência UML. Em um modelo UML, o modelo de armazenamento tem uma raiz, que é o modelo que possui todos os outros elementos; mas uma interação gerada existe em seu próprio armazenamento de modelo, que tem uma raiz nula:

    IModel rootModel = sequenceDiagram.ModelStore.Root;
    // !sequenceDiagram.UmlMode == (rootModel == null)

Para criar e exibir uma interação

Crie a interação como um filho de um pacote ou um modelo.

Por exemplo, se você estiver desenvolvendo um comando que pode ser executado em um diagrama de seqüência em branco, você deve sempre comece verificando se a interação existe.

public void Execute (IMenuCommand command)
{
    ISequenceDiagram sequenceDiagram = 
         Context.CurrentDiagram as ISequenceDiagram;
    if (sequenceDiagram == null) return;
    // Get the diagram's interaction:
    IInteraction interaction = sequenceDiagram.Interaction;
    // A new sequence diagram might have no interaction:
    if (interaction == null)
    {
       // Get the home package or model of the diagram:
       IPackage parentPackage = sequenceDiagram.GetObject<IPackage>();
       interaction = parentPackage.CreateInteraction();
       // Display the interaction on the sequence diagram:
       sequenceDiagram.Bind(interaction);
    } 

Atualizando uma interação e seu Layout.

Quando você atualiza uma interação, sempre termine sua operação atualizando seu layout usando um dos seguintes métodos:

  • ISequenceDiagram.UpdateShapePositions() Ajusta as posições das formas que recentemente foram inseridas ou movidas e seus vizinhos.

  • ISequenceDiagram.Layout([SequenceDiagramLayoutKinds])redesenha o diagrama inteiro. Você pode usar o parâmetro para especificar o reposicionamento das linhas de vida, as mensagens ou ambos.

Isso é particularmente importante quando você insere novos elementos ou move elementos existentes. Elas não estarão em posições corretas no diagrama até que você executou uma dessas operações. Você só precisará chamar uma dessas operações, uma vez no final de uma série de alterações.

Para evitar bemusing o usuário que executa um comando Desfazer após seu comando, use um ILinkedUndoTransaction para delimitar as alterações e o final Layout() ou UpdateShapePositions() as operações. Por exemplo:

using (ILinkedUndoTransaction transaction = LinkedUndoContext.BeginTransaction("create loop"))
{
  Interaction.CreateCombinedFragment(InteractionOperatorKind.Loop, messages);
  Diagram.UpdateShapePositions();
  transaction.Commit();
}

Para usar um ILinkedUndoTransaction, você deve fazer essa declaração na sua classe:

[Import] ILinkedUndoContext LinkedUndoContext { get; set; }

Para obter mais informações, consulte Como: Atualizações do modelo de link usando transações.

A criação de uma interação

Para criar linhas de vida

ILifeline lifeline = interaction.CreateLifeline();

Uma linha de vida representa um elemento conectável, ou seja, uma instância de um tipo. Por exemplo, se a interação é usada para mostrar como um componente delega as mensagens recebidas de suas partes internas, as linhas de vida podem representar as portas e partes do componente:

foreach (IConnectableElement part in 
            component.Parts
           .Concat<IConnectableElement>(component.OwnedPorts))
{
   ILifeline lifeline = interaction.CreateLifeline();
   lifeline.Represents = part;
}

Como alternativa, se a interação mostra um conjunto arbitrário de objetos, você pode criar uma propriedade ou outros IConnectableElement na interação propriamente dita:

ILifeline lifeline = interaction.CreateLifeline();
IProperty property1 = interaction.CreateProperty();
property1.Type = model.CreateInterface();
property1.Type.Name = "Type 1";
lifeline.Represents = property1;

Como outra alternativa, você pode definir o nome e o tipo de uma linha de vida sem vinculá-la a um elemento conectável:

ILifeline lifeline = interaction.CreateLifeline();
lifeline.Name = "c1";
lifeline.SetInstanceType("Customer");
System.Diagnostics.Debug.Assert(
           lifeline.GetDisplayName() == "c1:Customer"  );

Para criar mensagens

Para criar uma mensagem, você deve identificar os pontos de inserção na vida de origem e destino. Por exemplo:

interaction.CreateMessage( sourceInsertionPoint, 
                           targetInsertionPoint, 
                           MessageKind.Complete, 
                           MessageSort.ASynchCall)

Para criar uma mensagem que tenha uma indefinido de origem ou destino indefinido:

interaction.CreateLostFoundMessage(MessageKind.Found, insertionPoint);

Há a várias mensagens que você pode usar para identificar os pontos de inserção em todos os pontos-chave em uma linha de vida:

Método ILifeline

Usada para inserir neste momento

FindInsertionPointAtTop()

Na parte superior da linha de vida.

FindInsertionPointAtBottom()

Na parte inferior da linha de vida.

FindInsertionPointAfterMessage

(IMessage previous)

Um ponto imediatamente após a mensagem especificada.

FindInsertionPointAfterExecutionSpecification

(IExecutionSpecification previous)

O ponto pode ser da linha de vida ou em um bloco de especificação de execução do pai.

FindInsertionPointAfterInteractionUse

(IInteractionUse previous)

Um ponto após o uso de uma interação.

FindInsertionPointAfterCombinedFragment

(ICombinedFragment previous)

Um ponto em que um fragmento combinado a seguir.

FindInsertionPoint(IExecutionSpecification block)

Na parte superior de um bloco de execução.

FindInsertionPoint(IInteractionOperand fragment)

Na parte superior de um operando de um fragmento combinado.

Quando você criar mensagens, tome cuidado para evitar a definição de uma mensagem que passa pela outra mensagem.

Para criar os fragmentos combinados e interação usa

Você pode criar fragmentos combinados e interação usa especificando um ponto de inserção em cada linha de vida que deve ser coberta pelo elemento. Tome cuidado para evitar a especificação de um conjunto de pontos que passa através de uma mensagem existente ou um fragmento.

Interaction.CreateCombinedFragment(InteractionOperatorKind.Loop, 
  Interaction.Lifelines.Select(lifeline => lifeline.FindInsertionPointAtTop()));
Interaction.CreateInteractionUse(
  Interaction.Lifelines.Select(lifeline => lifeline.FindInsertionPointAtTop()));

Você também pode criar um fragmento combinado que abrange um conjunto existente de mensagens. Todas as mensagens devem ser originadas na mesma linha de vida ou bloco de execução.

ICombinedFragment cf = Interaction.CreateCombinedFragment(
  InteractionOperatorKind.Loop,
  Interaction.Lifelines.First().GetAllOutgoingMessages());

Um fragmento combinado é sempre criado com um único operando. Para criar um novo operando, você deve especificar o operando existente que você deseja inserir antes ou depois, e se você deseja inserir depois ou antes dele:

// Create an additional operand before the first
cf.CreateInteractionOperand(cf.Operands.First(), false);
// Create an additional operand after the last:
cf.CreateInteractionOperand(cf.Operands.Last(), true);

Solução de problemas

As formas aparecerão em posições incorretas se as alterações não são concluídas com um UpdateShapePositions() ou Layout() operação.

A maioria dos outros problemas são causados por pontos de inserção fique desalinhado, para que novas mensagens ou fragmentos teria cruzamento com outras pessoas. Os sintomas podem ser que nenhuma alteração é realizada, ou uma exceção é lançada. A exceção não pode ser lançada até que o UpdateShapePositions() ou Layout() operação é executada.

Consulte também

Referência

Microsoft.VisualStudio.Uml.Interactions

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 um Item da caixa de ferramentas de modelagem de personalizado