共用方式為


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

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

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

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

基本程式碼

Ee349042.collapse_all(zh-tw,VS.110).gif命名空間匯入

您必須包含下列 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:在模型圖表上定義功能表命令

Ee349042.collapse_all(zh-tw,VS.110).gif取得內容

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

    [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(zh-tw,VS.110).gif產生的順序圖表和 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:使用交易連結模型更新

建置互動

Ee349042.collapse_all(zh-tw,VS.110).gif若要建立生命線

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

Ee349042.collapse_all(zh-tw,VS.110).gif若要建立訊息

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

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)

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

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

Ee349042.collapse_all(zh-tw,VS.110).gif若要建立合併片段和互動使用

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

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 進行程式設計