繪制文檔視圖
設計器的主要工作之一就是繪制文檔視圖。其繪制過程一般是:
設計器控件重載它的OnPaint成員或綁定Paint事件。
當操作系統需要重新繪制設計器控件時會觸發它的Paint事件。
設計器獲得繪制圖形使用的System.Drawing.Graphics對象和一個表示繪制區域的剪切矩形ClipRectangle,然後將其作為參數調用文檔對象的RefreshVIEw函數。
文檔對象進行一個初始化工作,然後遍歷對象樹結構,找到所有和剪切矩形粘邊的文檔元素,調用它們的RefreshVIEw函數,讓各個元素繪制各自內容。
當所有工作完畢,則文檔視圖繪制完畢。
設計器繪制文檔是遇到一個難題就是閃爍,當用戶滾動視圖和更新視圖時,用戶界面很容易出現閃爍,過多的閃爍會比較嚴重的影響使用者的使用。關於閃爍的原理我曾經寫過一篇文章討論了一下(點擊查看)。由於設計文檔是比較復雜的文檔,繪制整個文檔視圖工作量大,繪制時間長,因此需要采用各種優化來減少繪制時間,減少閃爍。
對於閃爍有一個算是一勞永逸的辦法就是使用雙緩沖技術。在繪制圖形時,首先將圖形繪制到一個內存中的BMP圖片上,然後將這個BMP圖片繪制到用戶界面上。這種方法可以最大程度的減少閃爍,而且在.Net中使用雙緩沖也比較簡單。但我不大使用雙緩沖技術,有兩個原因
雙緩沖實際上增加了整個繪制文檔的工作量,延長了繪圖時間。當用戶滾動視圖時,會造成視圖很“沉重”的感覺,用戶界面響應遲鈍。
雙緩沖掩蓋了程序的不足之處。開發人員可以根據閃爍程度來判斷繪圖操作是否需要優化,以及優化效果。但雙緩沖消滅了閃爍,開發人員也就沒有優化繪圖操作的迫切需求,助長了開發人員的懶惰。程序繪制圖形時緩慢不堪,而很難從表面看出問題的可能原因。
其實可以這樣,設計器在開發時不使用雙緩沖,但發布時則使用雙緩沖。
由於設計器采用直角坐標方式,因此各個元素間存在相互覆蓋的關系,當存在大面積的覆蓋時,繪制文檔時必需要針對這種情況進行優化處理來提高繪制文檔的速度,減少計算機屏幕閃爍。針對覆蓋現象而進行優化時可以進行矩形覆蓋操作,對於矩形覆蓋操作,本人有另一篇文章對此進行了說明(點擊查看)。設計器繪制某個元素時,首先針對這個元素進行矩形覆蓋運算,將運算結果作為RefreshVIEw函數的某個參數來傳入,當文檔元素內容比較多時,可以根據這個矩形覆蓋運算結果來減少繪制量,提高繪制速度。
設計視圖還應提供縮放顯示功能,可以放大設計視圖來更清楚的顯示細節,可以縮小設計視圖來總體的把握整個文檔。GDI+有個轉換矩陣,可以很容易的實現設計視圖的縮放顯示。但此時所有的鼠標坐標數據都得進行相應的縮放處理。
設計視圖控件
設計視圖控件是設計器在用戶界面上的展示接口。它是一個標准的Windows控件,該控件派生自System.Windows.Form.UserControl。用戶使用鼠標和鍵盤在這個控件裡面編輯文檔,它重載了OnMouseDown , OnMouseMove 和 OnMouseUp 成員,對鼠標消息進行了一下包裝後供設計文檔對象使用。重載了OnPaint 成員來更新文檔視圖。重載了 OnDoubleClick 來進行試圖直接編輯文檔元素的文本內容。
當用戶設置某個元素為當前元素,則設計視圖控件將根據需要來進行滾動以便當前元素出現在可視區域中。若當前元素大小小於可視區域大小,則處理比較簡單,只要根據可視區域大小和元素在視圖中的位置就可計算滾動位置。若元素寬度或高度大於可視區域的寬度和高度,則需要進行額外的判斷,以避免滾動時發生跳躍。
鷹眼技術
一個好的設計器應當支持鷹眼技術,所謂鷹眼,通俗的講就是小地圖,它一般放置在程序界面的某個角落,它的面積不大,主要功能是讓人瞥上一眼就能大體了解整個文檔的結構,並能通過鼠標點擊快速的滾動文檔。關於鷹眼,本人寫過一個文章專門討論了它(點擊查看)。
總結
使用方便的所見即所得的設計器是一個復雜的程序,需要豐富的相關開發經驗,它涉及到圖形化,文檔對象模型以及其他各種編程技術,是一個多種編程技術的有機混合,通常需要編寫數萬行的代碼才能實現。因此其技術門檻比較高,一般的小公司沒有能力完成,即使有些公司有實力開發,那也要花數月的時間,有可能影響公司正常的項目開發。但隨著各種信息系統越來越靈活,它們必須配備良好的設計器,若有一個使用方便功能強大的設計器,則處理這種系統配置是事半功倍的,因此很多開發人員都不得不面對開發設計器這個技術難題。
有鑒於此,XDesigner軟件工作室憑著自身豐富的設計器開發經驗開發了XDesignerLib,一個設計器中間件,也就是一個設計器的半成品,這個中間件實現了所見即所得的設計器的全部基礎,並提供了非常充分的擴展接口。開發人員了解了XDesignerLib以後就可以僅僅編寫比較簡單的幾千行代碼就能實現一個功能強大的設計器。借助XDesignerLib,開發人員不必處理非常繁瑣的底層細節,只需了解XDesignerLib的接口,擴展它就行了。實事上XDesigner工作室已經開發的各種設計器都是基於XDesignerLib的。關於XDesigner軟件工作室和XDesignerLib,請訪問http://www.xdesigner.cn 。
本文是XDesigner軟件工作室撰寫,XDesigner軟件工作室擁有本文版權,轉載請注明出處,並保留本版權聲明。