HOW TO:使用交易連結模型更新
在 Visual Studio Ultimate 中定義 UML 設計工具的擴充功能時,可以將數個變更組成單一異動,稱為「連結的復原內容」(Linked Undo Context)。
根據預設,您對模型進行的每個修改都可以由使用者進行分別復原。 例如,如果定義功能表命令,交換兩個 UML 類別的名稱,則使用者可以叫用該命令,然後執行單一復原。 這樣會復原對一個名稱的變更,而不會復原其他名稱的變更,從而使模型處於未預期狀態。
若要避免此情況,可以撰寫程式碼,在異動內執行一系列變更。 這樣對使用者來說,多個變更就像是單一變更。 後續復原命令會復原整個系列。
另外一個優點是程式碼還可以透過擲回例外狀況或中止異動,來復原部分完成一組變更。
若要將變更分組為單一異動
確保專案參考包含以下 .NET 組件:
Microsoft.VisualStudio.Modeling.Sdk.10.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();
}
}