WYSIWYG 設計器是複雜系統配置工具的核心。本文系統闡述直角座標制設計器的架構:文檔物件模型 (DOM)、視覺化渲染、滑鼠鍵盤交互、XML 序列化、擴展機制等關鍵技術。
| 類型 | 代表產品 | 特徵 |
| 直角座標制 | Visio、VS WinForms 設計器 | 元素絕對定位 (X,Y)、支援重疊、大量拖曳操作 |
| 流式排版 | Word、HTML 編輯器 | 元素自動流動佈局、光標編輯、較少重疊 |
本文專注直角座標制設計器。
文檔物件模型 (DOM) 三層架構
- DesignElement (抽象基類):通用介面、XML 序列化、視圖渲染、滑鼠事件、樹狀結構維護
- DesignDocument (根節點):文檔整體載入/儲存、樹遍歷入口、腳本介面
- 具體元素類別:矩形、線段、容器、文字、表格、圖片、控件模擬等
基礎元素核心介面
public abstract class DesignElement {
// 樹狀結構
public DesignDocument OwnerDocument { get; set; }
public DesignElement Parent { get; set; }
public ElementCollection Items { get; }
// XML 序列化
public virtual void LoadFromXml(XmlElement elem) { }
public virtual void SaveToXml(XmlElement elem) { }
// 視圖渲染
public virtual void RefreshSize() { } // 自動計算尺寸
public virtual void RefreshView(Graphics g, Rectangle clipRect) { }
// 滑鼠事件 (座標已轉為元素局部座標)
public virtual void HandleMouseDown(MouseEventArgs e) { }
public virtual void HandleMouseMove(MouseEventArgs e) { }
public virtual void HandleMouseUp(MouseEventArgs e) { }
public virtual void HandleDoubleClick() { }
}
XML 序列化策略
採用子元素而非屬性儲存資料:
<DesignRectangleElement>
<Bounds>10,20,100,50</Bounds>
<FillColor>#FF0000</FillColor>
<ChildElements>
<DesignTextElement>...</DesignTextElement>
</ChildElements>
</DesignRectangleElement>
優點:易讀、易擴展、多行文字友善、版本相容性佳。
視覺化渲染管線
- 控件
OnPaint 取得 Graphics 與 ClipRectangle
- 呼叫
Document.RefreshView(g, clipRect)
- 文檔遍歷樹狀結構,檢測元素邊界與剪裁矩形相交
- 相交元素呼叫
RefreshView 繪製
- 矩形覆蓋優化:計算可見區域避免重複繪製被遮蓋部分
雙緩衝權衡
- 開發階段關閉:暴露閃爍倒逼渲染優化
- 發布階段開啟:
this.DoubleBuffered = true 消除殘留閃爍
滑鼠交互核心:8 控制點編輯
// 元素邊界矩形 8 個控制點
enum HandlePosition { None, TopLeft, Top, TopRight, Right, BottomRight, Bottom, BottomLeft, Move }
public HandlePosition HitTest(Point localPoint) {
// 計算滑鼠位於邊界、角點、內部還是外部
// 回傳對應控制點類型決定游標樣式
}
public void HandleMouseDown(MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
dragStartPoint = e.Location;
currentHandle = HitTest(e.Location);
if (currentHandle != HandlePosition.None) {
isDragging = true;
Capture = true;
}
}
}
public void HandleMouseMove(MouseEventArgs e) {
if (isDragging) {
// 繪製虛線框預覽
// 即時更新元素 Bounds
Invalidate(); // 觸發重繪
}
}
容器元素特殊處理
- 拖曳選取框而非移動容器本身
- 繪製子元素時執行矩形覆蓋運算
- 支援標題欄拖曳移動整個容器
擴展機制
- 繼承
DesignElement 實作新元素類型
- 重寫
RefreshView、RefreshSize、XML 序列化方法
- 註冊至元素工廠,設計器工具箱自動顯示
- 無需修改核心渲染與交互邏輯
輔助功能:鷹眼 (概覽圖)
縮略圖顯示整個文檔結構,點擊快速定位檢視區域。實作關鍵:同步縮放比例、檢視矩形同步、點擊座標映射。
開發建議
- 預期開發量:數萬行程式碼
- 考慮採用成熟中介庫 (如 XDesignerLib) 加速開發
- 核心難點:渲染效能、交互邊界情況、XML 版本遷移
- 測試策略:大文檔壓力測試、複雜巢狀容器、並發編輯模擬
- 上一篇文章: C# 實作哥德巴赫猜想驗證:偶數拆解為兩質數之和
- 下一篇文章: C# 3.0 隱式型別區域變數:var 關鍵字完整指南
Copyright ©
程式碼之家 All Rights Reserved