在基於 Visio 的繪圖系統中,必須精確掌握使用者對設備的新增、刪除、修改操作,才能確保資料一致性並支援圖紙版本管理。本文示範如何利用 Visio 事件模型建立完整的設備變更追蹤體系。
透過 Document.EventList.AddAdvise 監聽三類關鍵事件:
// 形狀新增
documentEvents.AddAdvise(
(short)VisEventCodes.visEvtAdd + (short)VisEventCodes.visEvtShape,
this, "", "ShapeAdd");
// 形狀刪除
documentEvents.AddAdvise(
(short)VisEventCodes.visEvtDel + (short)VisEventCodes.visEvtShape,
this, "", "ShapeDelete");
// 自訂屬性變更
documentEvents.AddAdvise(
(short)VisEventCodes.visEvtMod + (short)VisEventCodes.visEvtCell,
this, "", "CellChanged");
實作 IVisEventProc.VisEventProc 介面,依事件代碼分派處理:
switch (eventCode) {
case (short)VisEventCodes.visEvtShape + unchecked((short)VisEventCodes.visEvtAdd):
eventShape = (Shape)subject;
handleShapeAdd(eventShape);
break;
case (short)VisEventCodes.visEvtDel + (short)VisEventCodes.visEvtShape:
eventShape = (Shape)subject;
handleShapeDelete(eventShape);
break;
case (short)VisEventCodes.visEvtCell + (short)VisEventCodes.visEvtMod:
var cell = (Cell)subject;
if (cell.Name.IndexOf("Prop") >= 0) { // 僅處理自訂屬性
eventShape = cell.Shape;
handleCellModify(eventShape);
}
break;
}
Dictionary<string, ShapeLogInfo> 便於快速查找。private void visioEventSink_OnShapeDelete(object sender, EventArgs e) {
Shape shape = (Shape)sender;
string deviceType = VisioUtility.GetShapeCellValue(shape, "設備類型");
string deviceId = VisioUtility.GetShapeCellValue(shape, "GUID");
var logInfo = new ShapeLogInfo {
ShapeType = deviceType,
ShapeID = shape.NameID,
ShapeName = VisioUtility.GetShapeCellValue(shape, "名稱"),
ShapeGuid = deviceId,
ShapeStatus = ShapeStatus.DeleteShape
};
// 處理 Undo/Redo 導致的刪除:從既有日誌取回 GUID
if (shape.Application.IsUndoingOrRedoing) {
var existing = Portal.gc.gOperationLog.GetShape(deviceType, shape.NameID);
if (existing != null) logInfo.ShapeGuid = existing.ShapeGuid;
}
Portal.gc.gOperationLog.AddLog(logInfo);
}
此機制讓系統能即時記錄每筆變更,支援後續的資料庫同步、撤銷重做、版本比對等高階功能,是專業級 Visio 應用的基石。