HOW TO:使用交易連結模型更新

在 Visual Studio Ultimate 中定義 UML 設計工具的擴充功能時,可以將數個變更組成單一異動,稱為「連結的復原內容」(Linked Undo Context)。

根據預設,您對模型進行的每個修改都可以由使用者進行分別復原。例如,如果定義功能表命令,交換兩個 UML 類別的名稱,則使用者可以叫用該命令,然後執行單一復原。這樣會復原對一個名稱的變更,而不會復原其他名稱的變更,從而使模型處於未預期狀態。

若要避免此情況,可以撰寫程式碼,在異動內執行一系列變更。這樣對使用者來說,多個變更就像是單一變更。後續復原命令會復原整個系列。

另外一個優點是程式碼還可以透過擲回例外狀況或中止異動,來復原部分完成一組變更。

若要將變更分組為單一異動

確保專案參考包含以下 .NET 組件:

Microsoft.VisualStudio.Modeling.Sdk.11.0.dll

在類別中宣告具有 ILinkedUndoContext 型別的已匯入屬性:

using Microsoft.VisualStudio.Modeling.ExtensionEnablement;

...

class … {

[Import]

public ILinkedUndoContext LinkedUndoContext { get; set; }

在修改模型的方法中,將變更置於異動之內:

using (ILinkedUndoTransaction transaction =

LinkedUndoContext.BeginTransaction("my updates"))

{

// code to update model elements or shapes goes here

transaction.Commit();

}

請注意以下幾點:

  • 您必須一律將 Commit() 包含於異動的結尾。如果在沒有得到認可的情況下處置異動,則會復原該異動。也就是說,模型會還原至異動開始時的狀態。

  • 如果發生異動內沒有攔截到的例外狀況,則會復原異動。常用的模式是將異動的 using 區塊置於 try…catch 區塊內。

  • 您可以進行巢狀異動。

  • 您可以為 BeginTransaction() 提供任何非空名稱。

  • 這些異動只會影響「UML 模型存放區」。模型異動不會影響:變數、外部存放區 (例如檔案和資料庫)、圖層圖表、從程式碼產生的順序圖表和程式碼模型。

 範例

    using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
    using Microsoft.VisualStudio.Uml.Interfaces;
    using Microsoft.VisualStudio.Uml.Classes;
    using Microsoft.VisualStudio.Uml.Extensions;
    using System.Linq;
    using System.ComponentModel.Composition;
 ...
  [Import]
  public ILinkedUndoContext LinkedUndoContext { get; set; }

  /// <summary>
  /// Swap the names of the currently selected elements.
  /// </summary>
  public void Execute(IMenuCommand command)
  {
    var selectedShapes =
      Context.CurrentDiagram.GetSelectedShapes<IClassifier>();
    if (selectedShapes.Count() < 2) return;
    IClassifier firstElement = selectedShapes.First().Element;
    IClassifier lastElement = selectedShapes.Last().Element;
    string firstName = firstElement.Name;
    // Perform changes inside a transaction so that undo
    // works as a single change.
    using (ILinkedUndoTransaction transaction = 
      LinkedUndoContext.BeginTransaction("Swap names"))
    {
        firstElement.Name = lastElement.Name;
        lastElement.Name = firstName;
        transaction.Commit();
    }
 }

請參閱

概念

使用 UML API 進行程式設計

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

擴充 UML 模型與圖表