2009年1月2日 星期五

PropertyGrid控制項1-1

RunPC 111期:在.NET上保存應用程式設定(三)

什麼PropertyGrid控制項元件呢?如果讀者有使用過早期的Visual Basic或現今的Visual Studio.NET IDE(整合開發環境)開發環境,一定對『屬性視窗』的簡易設定、快速反映和良好的互動有著深刻的體會,顯然地『屬性視窗』已成為微軟快速應用程式開發(Rapid Application Development;RAD)不可獲缺的重要元素之一,這也是初學者為什麼這麼快就愛上VB的其中一項原因了。看到這兒讀者是否會想到,如果可以將IDE中的屬性視窗延伸到我們程式執行時期(Run-Time),那可不妙哉!沒錯這正式我們接下來所要聊的.NET Framework所提供的這項類別物件『PropertyGrid控制項元件』,它是Visual Studio.NET中屬性視窗的核心。
在開始PropertyGrid控制項元件的介紹之前,讓我們先回顧早期Visual Basic和今時Visual Studio.NET IDE內的屬性視窗有著何許差異,若單純由外觀呈現的方式來區分:Visual Studio.NET IDE內的屬性視窗除具有早期VB屬性視窗的[物件方塊]、[屬性清單]的[字母順序]和[性質分類]頁籤和[說明窗格]外,還加了一些特點,我們以字型(Font)為例,早期只可借由開啟[屬性頁]來做相關字型大小、字型樣式、效果…等字型細節設定,而今可多一項選擇可直接由屬性視窗直接展開Font階層來做相關細節設定,請見(圖一),當然如果您有設定相關圖示選項屬性時,屬性視窗亦會提供圖示預視縮圖的功能,除此之外還加上屬性預設值異動標明功能,如將Font由[新細明體]改為[標楷體],於Visual Studio.NET IDE的屬性視窗內可見Font內的值是以粗體顯示…等。

(圖一)早期VB與VS.NET屬性視窗介面上的差異

以上介紹的是介面呈現上的差異,接下來讓我們來看看早期與現今本質上的差異,先前版本是處理COM型態資訊是UnManage的,通常以IDL(Interface Definition Language)來定義COM公開的API,而它有組相關連的Attributes(特性)集合是用來定義屬性部份,如:nonbrowsable(是用來防止屬性被瀏灠);bindable(是用來標記為適用data-bind的屬性)……等,而在.NET Framework、Visual Studio.NET是利用.NET Framework上Manage的Windows Forms類別,它可以讓我們更簡易且更統一的方法來提供更多現行和新的功能,在比較過早期與現行本質上與外觀介面呈現上的差異後,讓我們來看一個簡單的例子。

利用PropertyGrid控制項於Run-Time時期控制控制項屬性設定值:

1、 建立Windows應用程式新專案:
從[開始][所有程式][ Microsoft Visual Studio .NET][ Microsoft Visual Studio .NET]開啟Visual Studio .NET IDE於[啟始頁]視窗中的[專案]頁籤中按[新增專案],在新增專案對話盒內的[專案類型]選擇[Visual Basic專案]資料夾,在[範本]中選擇[Windows應用程式],最後修改[名稱]為『PropertyGrid_WinAp』按確定,至此我們建立一個名稱為『PropertyGrid_WinAp』的Windows應用程式專案。
2、 加入PropertyGrid控制項到工具箱中:
一般在我們開啟專案後在工具箱中預設並不會把[PropertyGrid控制項]加入,我們必須以手動的方式將它加入以便使用,其操作步驟:從 [工具] 功能表中選取 [自訂工具箱],在對話方塊中選取 [.NET Framework 元件] 索引標籤,然後在鍵盤上按[P]快速找到以P為開頭的控制項後選取 [PropertyGrid]控制項按確定,再到[工具箱]的頁籤中即可找尋到圖示如: 的[PropertyGrid控制項]。
3、 加入控制項到表單中:
從工具箱中一如往常的將[PropertyGrid]、[TextBox]、[Label]、[ComboBox]等控制項一一拖曳至表單上,將PropertyGrid控制項名稱改為MyPropertyGrid,其餘使用預設名稱。
4、 撰寫相關程式碼:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Obj As Object
For Each Obj In Me.Controls
ComboBox1.Items.Add(Obj.name)
Next
End Sub

上面的程式碼是於Form1_Load事件中(即表單載入時)將在表單上的每一個控制項名稱列舉在ComboBox1下拉選單中,此處的Me代表表單本身。

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim Obj As Object
For Each Obj In Me.Controls
If Obj.name = sender.SelectedItem Then MyPropertyGrid.SelectedObject = Obj : Exit Sub
Next
End Sub

將表單上所有的控制項名稱加入ComboBox1下拉選單中後,接下來我們在ComboBox1_SelectedIndexChanged事件中(即ComboBox1選項改變時),將選中的物件設定給MyPropertyGrid.SelectedObject即在MyPropertyGrid方格中顯示該物件的屬性。
5、 執行與檢驗
請按[F5]執行,在ComboBox1中選擇我們要在MyPropertyGrid方格中顯示該物件屬性的控制項名稱,即可立即於MyPropertyGrid控制項中見到所選擇控制項的屬性,如(圖二)。
若要修改Label1的前景顏色為紅色,一如設計時期(Design-Time)修改屬性視窗中的設定值一般,將其ForeColor設為紅色即可,如(圖三) Label1的前景顏色立即轉為紅色,看到這兒讀者是否和筆者一樣感到份驚奇與興奮呢?該控制項讓誐們將設計時期做的事延伸到執行時期耶!


(圖二)於[PropertyGrid] 控制項方格中顯示[Label1]控制項的屬性



(圖三) 利用[PropertyGrid] 控制項將設計時期做的事延伸到執行時期

6、 應用與思考
在應用程式開發的過程中有種防止使用者鍵入錯誤的資料,或甚提醒、導引使用者鍵入應建立的資料,我們稱之為『防呆』的作法,而列舉選項給使用者來操作也是其中一項防呆的作法,而我們怎麼利用[PropertyGrid] 控制項來將應用程式作得更Smart呢?例:若在ComboBox2下拉選單是列舉敝公司年度公司旅遊方案,方案一:購買住宿卷二張;方案二:北台灣二天一夜遊;方案三:南台灣二天一夜遊供各位同仁選擇參考,但後來經主管裁示方案四:買住宿卷一張+北台灣一日遊;方案五:買住宿卷一張+南台灣一日遊此二方案,但此時投票系統已開發完成,是故只能在Run-Time時間來改變設定,請見(圖四)在ComboBox1下拉選單中選擇ComboBox2後於MyPropertyGrid方格中選擇[Items]叫出[字串集合編輯器],再輸入後二項方案即可在回到ComboBox2下拉即可看見共五個方案可供選擇,請見(圖五)是不是變得很Smart呢?不過投票這事,似乎也只是投票而已,一點也都不Smart,票數只不過是個Stupid的數字遊戲絲毫不具任何意義。


(圖四)原下拉選單



(圖五) 在執行時期動態加入下拉項目

到目前為止我們介紹的是由工具箱中拖曳[PropertyGrid] 控制項,然後才撰寫相關的程式碼,使其可以在Run-Time時設定控制項物件的相關屬性,接下來我們要介紹的是怎麼樣利用程式碼類別的方式來建立與呈現物件的相關屬性,其步驟如下:

1、 在原專案[PropertyGrid_WinAp]的方案總管中選右鍵,於快顯功能表中選[加入][加入新項目],在範本中選擇[類別],更名為[ClsProGrid],按[確定]建立新類別。
2、 輸入以下程式碼:

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class ClsProGrid
Inherits System.Windows.Forms.Form
Private ProGrid As PropertyGrid
Public Sub New()
MyBase.New()
ProGrid = New PropertyGrid()
ProGrid.Size = New Size(300, 500)
ProGrid.SelectedObject = ProGrid
Me.Controls.Add(ProGrid)
Me.Text = "執行時期屬性視窗"
End Sub
End Class

上面程式碼Imports的部份是匯入的命名空間(Namespace),我們使用System.Drawing命名空間內的Size結構來設定PropertyGrid控制項的大小,而我們使用System.Windows.Forms命名空間下的PropertyGrid類別來建立該控制項(註1),ProGrid.SelectedObject = ProGrid呈現本身的屬性;Me.Controls.Add(ProGrid)將ProGrid加入至表單上。
註1:若專案要使用到的共通命名空間(Namespace),我們可以將其命名空間匯入於專案層內,而非於每個類別或表單內加入Imports敘述,如上我們可以將Imports System、System.Drawing、System.Windows.Forms三行敘述去除,而在[專案屬性頁]內的[通用屬性]下的[匯入]中將System、System.Drawing、System.Windows.Forms命名空間加入匯入至專案匯入區即可(圖六)。


(圖六)匯入專案層級的命名空間

3、 設定啟始物件:在執行之前我們需改變它的啟始物件,如(圖七)選擇啟始物件為[ClsProGrid],後按確定,執行即可見著如(圖八)之畫面。


(圖七)修改啟始物件



(圖八)執行時期屬性視窗

看到這兒各位是否會有個疑問,難到PropertyGrid只可顯示一般系統所提供的控制項類別物件的屬性嗎?我們可以依照我們的需求來自訂自已所屬的類別物件於PropertyGrid控制項中顯示嗎?答案當然是可以的,如此做的話將建立一個自訂獨立的類別,而非使用各別控制項,設定會較簡單且容易管理維護,將不必要或較細節的部分隱藏起來,接下讓我們繼續探索[PropertyGrid]控制項的奧祕吧!

加入書籤: MyShare HemiDemi Baidu Google Bookmarks Yahoo! My Web PChome Del.icio.us Digg technorati furludn bookmark 其他更多書籤

BOOKS:New and Upcoming