Freigeben über


Gewusst wie: Bearbeiten von Sequenzdiagrammen mit der UML-API

Eine Interaktion ist eine Sequenz von Meldungen zwischen einem Satz von Lebenslinien.Eine Interaktion wird in einem Sequenzdiagramm angezeigt.

Detaillierte Informationen zur API finden Sie unter Microsoft.VisualStudio.Uml.Interactions.

Eine allgemeine Einführung in das Schreiben von Befehls- und Gestenhandlern für UML-Diagramme finden Sie unter Gewusst wie: Definieren eines Menübefehls in einem Modellierungsdiagramm.

Grundlegender Code

Ee349042.collapse_all(de-de,VS.110).gifNamespaceimporte

Sie müssen die folgenden using-Anweisungen einschließen:

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

Wenn Sie Menübefehle und Gestenhandler erstellen, benötigen Sie auch Folgendes:

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

Weitere Informationen finden Sie unter Gewusst wie: Definieren eines Menübefehls in einem Modellierungsdiagramm.

Ee349042.collapse_all(de-de,VS.110).gifAbrufen des Kontexts

Wenn Sie eine Interaktion als Teil eines Befehls- oder Gestenhandlers in einem Sequenzdiagramm bearbeiten, können Sie einen Verweis auf den Kontext abrufen.Beispiele:

    [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;
             ...

Ee349042.collapse_all(de-de,VS.110).gifGenerierte Sequenzdiagramme und UML-Sequenzdiagramme

Es gibt zwei Arten von Sequenzdiagrammen: manuell in einem UML-Modellierungsprojekt erstellte Diagramme und per Programmcode generierte Diagramme.Sie können die UmlMode-Eigenschaft verwenden, um die Art des Sequenzdiagramms zu ermitteln.

Wenn Sie z. B. einen Menübefehl erstellen möchten, der nur in UML-Sequenzdiagrammen sichtbar ist, könnte die QueryStatus()-Methode die folgende Anweisung enthalten:

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

Die Lebenslinien, Meldungen und anderen Elemente in einem generierten Sequenzdiagramm ähneln denen eines UML-Sequenzdiagramms weitgehend.Bei einem UML-Modell ist das Modell, das der Besitzer aller anderen Elemente ist, der Stamm des Modellspeichers, es besteht jedoch eine generierte Interaktion in seinem eigenen Modellspeicher, dessen Stamm NULL ist:

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

So erstellen Sie eine Interaktion und zeigen Sie sie an

Erstellen Sie die Interaktion als untergeordnetes Element eines Pakets oder Modells.

Wenn Sie z. B. einen Befehl entwickeln, der für ein leeres Sequenzdiagramm ausgeführt werden kann, sollten Sie immer zuerst überprüfen, ob die Interaktion vorhanden ist.

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);
    } 

Aktualisieren einer Interaktion und ihres Layouts

Wenn Sie eine Interaktion aktualisieren, sollten Sie abschließend immer das Layout der Interaktion mit einer der folgenden Methoden aktualisieren:

  • ISequenceDiagram.UpdateShapePositions() passt die Positionen von kürzlich eingefügten oder verschobenen Formen und der benachbarten Formen an.

  • ISequenceDiagram.Layout([SequenceDiagramLayoutKinds]) zeichnet das gesamte Diagramm neu.Sie können mithilfe des Parameters die erneute Positionierung der Lebenslinien und/oder der Meldungen angeben.

Dies ist besonders wichtig, wenn Sie neue Elemente einfügen oder vorhandene Elemente verschieben.Ihre Positionen im Diagramm sind erst dann korrekt, wenn Sie eine dieser Operationen ausgeführt haben.Sie müssen nur eine dieser Operationen am Ende einer Reihe von Änderungen aufrufen.

Verwenden Sie eine ILinkedUndoTransaction, um die Änderungen und die abschließenden Layout()- oder UpdateShapePositions()-Operationen einzuschließen. Andernfalls kann es zu Verwirrungen kommen, wenn ein Benutzer nach dem Ausführen Ihres Befehls eine Änderung rückgängig macht.Beispiele:

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

Zur Verwendung einer ILinkedUndoTransaction müssen Sie die folgende Deklaration in der Klasse hinzufügen:

[Import] ILinkedUndoContext LinkedUndoContext { get; set; }

Weitere Informationen finden Sie unter Gewusst wie: Verknüpfen von Modellaktualisierungen mithilfe von Transaktionen.

Erstellen einer Interaktion

Ee349042.collapse_all(de-de,VS.110).gifSo erstellen Sie Lebenslinien

ILifeline lifeline = interaction.CreateLifeline();

Eine Lebenslinie stellt ein verbindungsfähiges Element dar, also eine Instanz eines Typs.Wenn mit der Interaktion z. B. angezeigt werden soll, wie eine Komponente eingehende Meldungen an ihre internen Bestandteile delegiert, können die Lebenslinien Anschlüsse und Bestandteile der Komponente darstellen:

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

Falls die Interaktion einen beliebigen Satz von Objekten anzeigt, können Sie in der Interaktion selbst eine Eigenschaft oder ein anderes IConnectableElement-Element erstellen:

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

Eine weitere Alternative besteht darin, den Namen und Typ einer Lebenslinie festzulegen, ohne sie mit einem verbindungsfähigen Element zu verknüpfen:

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

Ee349042.collapse_all(de-de,VS.110).gifSo erstellen Sie Meldungen

Um eine Meldung zu erstellen, müssen Sie Einfügemarken auf den Quell- und Ziellebenslinien identifizieren.Beispiele:

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

So erstellen Sie eine Meldung, die über eine nicht definierte Quelle oder nicht definiertes Ziel verfügt:

interaction.CreateLostFoundMessage(MessageKind.Found, insertionPoint);

Sie können mehrere Meldungen verwenden, um an allen wichtigen Punkten auf einer Lebenslinie Einfügemarken anzugeben:

Methode auf ILifeline

Zum Einfügen an diesem Punkt verwenden

FindInsertionPointAtTop()

Das obere Ende der Lebenslinie.

FindInsertionPointAtBottom()

Das untere Ende der Lebenslinie.

FindInsertionPointAfterMessage

(IMessage previous)

Ein Punkt direkt nach der angegebenen Meldung.

FindInsertionPointAfterExecutionSpecification

(IExecutionSpecification previous)

Der Punkt kann sich entweder auf der Lebenslinie oder auf einem übergeordneten Ausführungsspezifikationsblock befinden.

FindInsertionPointAfterInteractionUse

(IInteractionUse previous)

Ein Punkt, der auf eine Interaktionsverwendung folgt.

FindInsertionPointAfterCombinedFragment

(ICombinedFragment previous)

Ein Punkt, der auf ein kombiniertes Fragment folgt.

FindInsertionPoint(IExecutionSpecification block)

Das obere Ende eines Ausführungsblocks.

FindInsertionPoint(IInteractionOperand fragment)

Das obere Ende eines Operanden aus einem kombinierten Fragment.

Achten Sie beim Erstellen von Meldungen darauf, dass sich die definierte Meldung nicht mit anderen Meldungen überkreuzt.

Ee349042.collapse_all(de-de,VS.110).gifSo erstellen Sie kombinierte Fragmente und Interaktionsverwendungen

Sie können kombinierte Fragmente und Interaktionsverwendungen erstellen, indem Sie eine Einfügemarke auf jeder Lebenslinie angeben, die vom Element abgedeckt werden muss.Die angegebenen Einfügemarken dürfen sich nicht mit vorhandenen Meldungen oder Fragmenten überkreuzen.

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

Sie können auch ein kombiniertes Fragment erstellen, das einen vorhandenen Satz von Meldungen abdeckt.Die Meldungen müssen alle aus der gleichen Lebenslinie oder dem gleichen Ausführungsblock stammen.

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

Ein kombiniertes Fragment wird immer mit nur einem Operanden erstellt.Wenn Sie einen neuen Operanden erstellen möchten, müssen Sie den vorhandenen Operanden angeben, den Sie davor oder danach einfügen möchten, und Sie müssen festlegen, ob er danach oder davor eingefügt werden soll:

// 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);

Problembehandlung

Formen werden an falschen Positionen angezeigt, wenn Änderungen nicht mit einer UpdateShapePositions()- oder Layout()-Operation abgeschlossen werden.

Die meisten anderen Probleme sind auf falsch ausgerichtete Einfügemarken zurückzuführen, durch die sich neue Meldungen oder Fragmente mit anderen überkreuzen.Symptome hierfür sind, dass keine Änderung ausgeführt oder eine Ausnahme ausgelöst wird.Die Ausnahme wird möglicherweise erst ausgelöst, wenn die UpdateShapePositions()- oder Layout()-Operation ausgeführt wird.

Siehe auch

Referenz

Microsoft.VisualStudio.Uml.Interactions

Konzepte

Erweitern von UML-Modellen und Diagrammen

Gewusst wie: Definieren eines Menübefehls in einem Modellierungsdiagramm

Gewusst wie: Definieren eines benutzerdefinierten Elements für die Modellerstellungstoolbox

Gewusst wie: Definieren von Validierungseinschränkungen für UML-Modelle

Programmieren mit der UML-API