UI(User Interface)編程在整個項目開發過程中是個頗為重要的環節,任何好的解決方案若沒有良好的用戶界面呈現給最終用戶,那麼就算包含了最先進的技術也不能算是好程序。UI編程體現在兩個方面,一是設計精美的用戶界面,再有就是符合大多數用戶習慣和易於使用的操作流程,而制作出精美的、絢麗多彩的用戶界面是博得最終用戶喜愛的第一步。我們就以制作一個水晶樣式的三維按鈕為例來豐富.Net界面素材庫,為Windows 窗體程序增加亮點。
一、 技術要點 不可否認的是,Windows編程已經進入.Net時代,雖然現在的編程平台仍然是多家並存,但是微軟的.Net框架類庫已經全面占據了主流地位。.Net框架為我們提供了非常豐富的類、函數和方法,從桌面到Web它可以觸及到編程的任何領域,以至於可以完全放棄Win32 API 的手工調用,因為.Net框架已經為我們准備好了一切。尤其是GDI+的發布,Win32程序員都應該非常清楚,在VC6和Delphi5、6、7下要想繪制不規則圖形、設計獨特樣式的窗口控件是件多麼不輕松的事情,我們需要返回當前設備指針,然後坐標映射,再調用標准的Win32 GDI函數來進行繪制操作,最後還得記著釋放設備指針等一系列內存清理操作,現在有了.Net類庫,我們只需在控件的OnPaint事件中通過e.Graphics返回Graphics對象,然後創建一個自定義的刷子對象Brush來填充Graphics表面,再創建一個Region對象設計好我們需要的控件輪廓,並將其賦給控件的Region屬性,在這個過程中可以使用GDI+為我們提供的豐富的類和方法來設計美輪美奂的控件外觀,這樣一個全新的控件就創建完成了。
我們的示例控件是一個水晶樣式的三維按鈕,設計這樣一個按鈕控件其實並不復雜,我們只需要捕獲OnPaint事件,並在事件中按照不同的按鈕狀態譬如:鼠標進入、鼠標懸停、鼠標單擊以及鼠標離開等重新繪制按鈕的外觀。按鈕的三維樣式實際上就是三個矩形區域的疊加,即陰影位於最底層、按鈕本身以及最頂層的按鈕頭部白色泡泡部分,這三部分有效的疊加就制作成了一個惟妙惟肖的水晶樣式的按鈕了,如下圖所示:
在這個示例中用到的比較關鍵的類是GraphicsPath、LinearGradientBrush和PathGradientBrush。我們已經知道,對於復雜的圖形繪制操作都會用到GraphicsPath對象,GraphicsPath為我們提供了一個非常方便的解決方案,它由一系列直線和曲線組成,通過創建復雜的閉合路徑,我們可以輕松創建任意不規則圖形;LinearGradientBrush和PathGradientBrush對象是我們成功創建該示例程序的關鍵類,它們都繼承於基類Brush,Brush對象定義用於填充圖形形狀的內部的對象。LinearGradientBrush按照起始和結束坐標以及漸變的起始和結束顏色來創建一個該類的實例,該類支持雙色漸變和自定義多色漸變,所有漸變都是沿由矩形的寬度或兩個點指定的直線定義的,默認情況下,雙色漸變是沿指定直線從起始色到結束色的均勻水平線性混合,所以,根據這個特性我們利用該類來繪制按鈕本身和按鈕頂部的白色漸變部分,部分代碼如下:
//創建按鈕本身的圖形
Rectangle rc = new Rectangle(btnOffset, btnOffset, this.ClientSize.Width - 8 - btnOffset, this.ClientSize.Height - 8 - btnOffset);
GraphicsPath path1 = this.GetGraphicsPath(rc, 20);
LinearGradientBrush br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rc.Height + 6), Color.Blue, Color.White);
//創建按鈕頂部的白色漸變
Rectangle rc3 = rc;
rc3.Inflate(-5, -5); //
rc3.Height = 15;
GraphicsPath path3 = GetGraphicsPath(rc3, 20);
LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical)
PathGradientBrush類通過漸變填充 GraphicsPath對象的內部,它可以從路徑的中點到路徑的外邊界邊緣的進行平滑的彩色漸變,我們利用該類來創建按鈕的陰影部分,CenterColor屬性用來設定路徑漸變的中心處的顏色即黑色,SurroundColors數組用來設定路徑中點相對應的顏色的數組,部分代碼如下:
Rectangle rc2 = rc;
rc2.Offset(shadowOffset, shadowOffset);
GraphicsPath path2 = this.GetGraphicsPath(rc2, 20);
PathGradientBrush br2 = new PathGradientBrush(path2);
br2.CenterColor = Color.Black;
br2.SurroundColors = new Color[] {SystemColors.ButtonFace};
//為了更逼真,我們將漸變結束顏色設定為窗體前景顏色,可以根據窗口的前景顏色適當調整
創建完該對象的實例後,陰影圖形的內部被填充為一個放射狀的漸變,也許讀者會問,為什麼得用PathGradientBrush填充圖形內部,而不用LinearGradientBrush呢?其實原因很簡單,就是為了保證按鈕下方和右方的陰影漸變顏色和程度是一致的,否則若還使用線性漸變LinearGradientBrush,結果就是這樣如下圖:
三個Brush對象的實例br1、br2和br3創建完成後,我們需要按照陰影、按鈕本身,最後是按鈕頂部的白色漸變部分這樣的順序來繪制它們。調用Graphics對象的FillPath方法分別使用三種不同的Brush對象來填充 GraphicsPath 的內部,這樣具備水晶樣式的三維按鈕就基本創建完成了。最後,我們再利用.Net二級緩存繪圖技術將按鈕以及按鈕上所顯示的文字繪制到屏幕上。