善用 .NET 的 PropertyGrid 控件

来源:百度文库 编辑:神马文学网 时间:2024/04/26 18:48:25

善用 .NET 的 PropertyGrid 控件

作者:蔡學鏞

2004 年 8 月

我經常需要寫程式設計出一套又一套的工具軟體。在設計工具程式時,常常會用到 Property 的觀念,那就是一個物件可以有許多的 Property,改變 Property 的設定,也就會改變物件本身。設計區內可以放置許多物件,設計區內的某物件一旦成為焦點 (selected),旁邊的 Property Panel 就會列出此物件的所有 Property,並可以在此設定 Property 的值。這樣的觀念,大家一定不陌生,因為不管是 Visual Studio 或 JBuilder,都是使用這樣的作法。

由於 Java Swing 並未提供 Property Panel 的控件,所以我必須自行撰寫 Property Panel。Property Panel 看起來固然很像 Java Swing 的 JTable,但是無法利用 JTable 來當作 Property Panel,因為在 JTable 中,每個直欄 (Column) 的資料類型必須一致,但以 Property Panel 來說,資料類型卻是不固定的,有的是 Boolean,有的是整數,有的是 Font,有的是 Color。所以無法利用 JTable 來當作 Property Panel,必須自行設計 Property Panel。

用 Java Swing 來自行打造一個 Property Panel,並不困難,只是很繁瑣。以我自己的經驗來說,我會設計一個名為 PropertyPanel 的類別,將 Property 名稱和 Property 值一一列出來。然後再設計一個 PropertyPanelContainer 類,並將它的 LayoutManager 設定為 CardLayout。每個物件都具有自己的 PropertyPanel 控件,一旦某物件被加入到設計區,就同時把該物件的 PropertyPanel 控件加到 PropertyPanelContainer。當某物件被選取,成為焦點物件,則請 CardLayout 將該物件的 PropertyPanel 顯示出來。如圖一所示。


圖 1

PropertyPanelContainer 的 LayoutManager 是 CardLayout,而 PropertyPanel 的 LayoutManager 則是 null,由我們自行控制控件的位置。左邊擺放的控件一律是 JLabel,用來顯示屬性名稱;右邊擺放的則是各種編輯控件,例如 JTextField、JCheckBox。PropertyPanel 內還必須放置一個細長而透明的控件,剛好放在左右控件的中間,且其 Z-Order 必須在最上層,用來感知滑鼠事件,來調整左右區域的大小。PropertyPanel 還必須搭配 JScrollPane 來使用,以產生垂直捲軸 (Scrollbar)。

另一種作法則更方便一些。直接使用 JSplittedPane 來負責左右位置的調整,如此一來,左右兩邊可以使用 BoxLayout 或 GridLayout 來負責控件的擺設。如圖二所示。


圖 2

事情還沒完,這一大堆控件的產生與管理、控件和物件 Property 的資料繫結 (data binding)、同時選取多個物件……等問題,都會讓程式員的困擾大增。

所幸,在 .NET 的環境中,有 PropertyGrid 控件可以幫我們。什麼是 PropertyGrid 控件,使用過 Visual Studio .NET 的人應該都看過圖三的控件,這就是 PropertyGrid。


圖 3

PropertyGrid 雖然是標準的 Windows Forms 控件,但是知道此控件的人可能不多,因為大多數的 Windows Forms 書籍並未介紹此控件,且在預設的情況下,PropertyGrid 並未被加入 Visual Studio 的工具箱 (Tool Box) 中。

欲將 PropertyGrid 加入工具箱,方法如下:

  • 在工具箱按下滑鼠右鍵,選擇「新增/移除項目(I)」,就可以看到「自訂工具箱」。
  • 在自訂工具箱內找到「PropertyGrid」,勾選 (check)。然後按下確定即可。

PropertyGrid 使用上很簡單,因為它內部使用 .NET 的 Data Binding 機制與 Reflection 機制,所以一切都變得很自動化。

PropertyGrid 有一個 property 為「SelectedObject」,用來指向所關連的物件。如下所示:

propertyGrid1.SelectedObject = myObject;

如果同時有多個物件被選取,則可以設定「SelectedObjects」屬性 (注意字尾有s):

propertyGrid1.SelectedObjects = myObjectArray;

PropertyGrid 會利用 Reflection 機制將關連物件內所有的屬性 (包括繼承來的屬性) 列出來。並根據屬性的類型,來決定其編輯控件為何 (程式員也可以自行設計編輯工具,但本文不介紹這種作法)。例如,類型如果是 Font,則其編輯控件為選擇自行的對話盒。甚至,當 property 本身是複合類型時,可以如同樹狀結構一般地展開 (如圖四所示)。


圖 4

當我們改變 PropertyGrid 內的值,則 Data Binding 機制會自動將其關連的物件做出修正。如果是在 Java,就會麻煩許多,因為必須攔截事件 (event),才能對物件進行修改。而在 .NET,這些全都不需要程式員操心。

PropertyGrid 有三個區域,分別是上面的工具列 (Toolbar),中間的 property list,以及下面的輔助說明列 (Help),如圖四所示。其中工具列用來選擇 property 的排列方式,輔助說明列用來顯示 property 的說明。工具列和輔助說明列都可以被移除,只要將 PropertyGrid 物件的 ToolbarVisible 和 HelpVisible 設為 false 即可。

我們可以將物件的 Property 分類,如此一來,以方便使用者在 PropertyGrid 內的找尋。在宣告 Property 的時候,利用 CategoryAttribute 來修飾此 Property 即可。我們也可以為 Property 加上說明,以方便使用者瞭解此 Property 的目的。在宣告 Property 的時候,利用 DescriptionAttribute 來修飾此 Property 即可,如下所示:

[Category("Color")][Description ("This is foreground color")]public string Foreground {get { … }set { … }}

如果想改變排序方式,只要設定 PropertyGrid 的 PropertySort 即可,可以設定為:

  • PropertySort.Alphabetical:依照字母順序排序。
  • PropertySort.Categorized:依照類別順序排序。
  • PropertySort.CategorizedAlphabetical:先依照類別再依照順序排序。
  • PropertySort.NoSort:不排序。

如果你不希望某些 Property 出現在 PropertyGrid 中,你可以利用 [Browsable(false)] 來修飾該 Property,例如:

[Browsable (false)]public Rectangle Rect {get { … }set { … }}

除此之外,PropertyGrid 也可以訂定過濾條件,來將符合條件的 Property 列出來,不符合條件的 Property 則不會列出來。例如:

propertyGrid1.BrowsableAttributes = new AttributeCollection(new Attribute[] {new A1Attribute(), new A2Attribute(true) });

上面的意思是,只有同時具備 A1Attribute() 以及 A2Attribute(false) 的 Property,才會被列在 PropertyGrid中。

直接利用 .NET 的 PropertyGrid 控件,比起 Java 必須自己設計這樣的控件,可以節省更多開發時間,而且 .NET的 PropertyGrid 控件功能更強大。使用到 PropertyGrid 控件的機會其實很多。希望大家讀過這篇文章之後,能夠從此以後善用 PropertyGrid。其實,.NET 的 Windows Forms 裡面還有許多方便的控件,等待我們去認識並善用。