共用方式為


HOW TO:使用 UML API 編輯順序圖表

互動是一組生命線之間的訊息系列。 順序圖表上會顯示互動。

如需 API 的詳細資料,請參閱Microsoft.VisualStudio.Uml.Interactions

如需為 UML 圖表撰寫命令和筆勢處理常式的一般介紹,請參閱 HOW TO:在模型圖表上定義功能表命令

基本程式碼

命名空間匯入

您必須包含下列 using 陳述式:

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

如果您要建立功能表命令和筆勢處理常式,您還需要:

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

如需詳細資訊,請參閱HOW TO:在模型圖表上定義功能表命令

取得內容

如果您以順序圖表中命令或筆勢處理常式的一部分編輯互動,則可以取得以下內容的參考。 例如:

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

產生的順序圖表和 UML 順序圖表

順序圖表有兩種:在 UML 模型專案中手動建立的圖表,以及從程式碼產生的圖表。 您可以使用 UmlMode 屬性探索您所處理的順序圖表類型。

例如,如果您要設定某個只會顯示在 UML 順序圖表上的功能表命令,則 QueryStatus() 方法可包含下列陳述式:

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

在產生的順序圖表中,生命線、訊息和其他項目都與 UML 順序圖表中的項目非常類似。 在 UML 模型中,模型存放區具有一個根,此為擁有所有其他項目的模型;但產生的互動會存在於其本身的模型存放區中,而此存放區具有 null 根:

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

若要建立及顯示互動

建立互動做為封裝或模型的子項。

例如,如果您要開發可在空白順序圖表上執行的命令,則一律應先檢查互動是否存在。

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

更新互動及其配置

在更新互動時,一律應在作業結束前使用下列其中一個方法更新互動的配置:

  • ISequenceDiagram.UpdateShapePositions() 會對最近插入或移動的圖案及其相鄰圖案調整位置。

  • ISequenceDiagram.Layout([SequenceDiagramLayoutKinds]) 會重新繪製整個圖表。 您可以使用此參數來指定重新定位生命線和 (或) 訊息。

這在您插入新項目或移動現有項目時尤其重要。 必須在您執行下列其中一項作業後,這些項目在圖表中才會位於正確的位置上。 您只需在完成一系列的變更時,呼叫其中一項作業一次即可。

請使用 ILinkedUndoTransaction 包住您的變更和最終的 Layout() 或 UpdateShapePositions() 作業,以免在您的命令後執行復原的使用者感到困惑。 例如:

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

若要使用 ILinkedUndoTransaction,您必須在類別中進行下列宣告:

[Import] ILinkedUndoContext LinkedUndoContext { get; set; }

如需詳細資訊,請參閱 HOW TO:使用交易連結模型更新

建置互動

若要建立生命線

ILifeline lifeline = interaction.CreateLifeline();

生命線代表可連接的項目,即型別的執行個體。 例如,如果互動用以顯示元件如何將傳入訊息委派至其內部組件,則生命線可代表元件的連接埠與組件:

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

或者,如果互動顯示任意物件集,則可以在互動自身中建立屬性或其他 IConnectableElement:

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

或者,您可以設定生命線的名稱和型別,而不將生命線連結至可連接項目:

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

若要建立訊息

若要建立訊息,您必須識別來源和目標生命線上的插入點。 例如:

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

若要建立具有未定義來源或未定義目標的訊息:

interaction.CreateLostFoundMessage(MessageKind.Found, insertionPoint);

您可以使用數則訊息來識別生命線上所有關鍵點的插入點:

生命線上的方法

使用該方法來在此點插入

FindInsertionPointAtTop()

生命線的頂端。

FindInsertionPointAtBottom()

生命線的底部。

FindInsertionPointAfterMessage

(IMessage previous)

緊接在指定之訊息後面的點。

FindInsertionPointAfterExecutionSpecification

(IExecutionSpecification previous)

該點可以位於生命線上,也可以位於父執行規格區塊上。

FindInsertionPointAfterInteractionUse

(IInteractionUse previous)

互動使用後面的點。

FindInsertionPointAfterCombinedFragment

(ICombinedFragment previous)

合併片段後面的點。

FindInsertionPoint(IExecutionSpecification block)

執行區塊的頂部。

FindInsertionPoint(IInteractionOperand fragment)

合併片段的運算元段頂部。

在建立訊息時,請避免定義會跨界到其他訊息上的訊息。

若要建立合併片段和互動使用

您可以建立合併片段和「互動使用」,方法是在每個生命線上指定必須由該項目涵蓋的插入點。 請避免指定會跨界到現有訊息或片段上的點集合。

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

您也可以建立會涵蓋現有的一組訊息的合併片段。 這些訊息必須全都來自於相同的生命線或執行區塊。

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

建立的合併片段一律會包含單一運算元。 若要建立新的運算元,您必須指定要在其之前或之後插入的現有運算元,以及要在其之前還是之後插入:

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

疑難排解

如果未以 UpdateShapePositions() 或 Layout() 作業完成變更,圖案將會出現在不正確的位置上。

其他的問題大多導因於插入點未對齊,而使新的訊息或片段必須跨界到其他訊息或片段上。 若未執行任何變更,或有例外狀況擲回,表示可能有此狀況。 在 UpdateShapePositions() 或 Layout() 作業執行前並不會擲回例外狀況。

請參閱

參考

Microsoft.VisualStudio.Uml.Interactions

其他資源

擴充 UML 模型與圖表

HOW TO:在模型圖表上定義功能表命令

HOW TO:定義自訂模型工具箱項目

HOW TO:定義 UML 模型的驗證條件約束

使用 UML API 進行程式設計