最近項目中做一模塊時偶發奇想,希望使用propertygrid的控制項實現類似visual studio的屬性樣式,於是拿來一用,發現還真不是自己想象的那麼簡單,如果要實現一個比較好的展示,還真的需要不少技巧,通過自己的實踐和網路的力量,“逢山開道,遇水搭橋”,總算是摸出一些門道,不敢私藏,拿出來與大 ...
最近項目中做一模塊時偶發奇想,希望使用propertygrid的控制項實現類似visual studio的屬性樣式,於是拿來一用,發現還真不是自己想象的那麼簡單,如果要實現一個比較好的展示,還真的需要不少技巧,通過自己的實踐和網路的力量,“逢山開道,遇水搭橋”,總算是摸出一些門道,不敢私藏,拿出來與大家分享,呵呵。
先來轉一個基礎的,源自msdn
http://www.microsoft.com/taiwan/msdn/library/2002/Jul-2002/article/usingpropgrid.htm
摘要: 本文旨在幫助您瞭解 Microsoft .NET 框架中的 PropertyGrid 控制項,以及如何針對您的應用程式自定義該控制項。
適用於:
Microsoft® .NET® 框架
Microsoft® Visual Studio® .NET
目錄
PropertyGrid 控制項簡介
創建 PropertyGrid 控制項
何處使用 PropertyGrid 控制項
選擇對象
自定義 PropertyGrid 控制項
顯示覆雜屬性
為屬性提供自定義 UI
PropertyGrid 控制項簡介
如果您使用過 Microsoft® Visual Basic® 或 Microsoft Visual Studio .NET,那麼您一定使用過屬性瀏覽器來瀏覽、查看和編輯一個或多個對象的屬性。.NET 框架 PropertyGrid 控制項是 Visual Studio .NET 屬性瀏覽器的核心。PropertyGrid 控制項顯示對象或類型的屬性,並主要通過使用反射來檢索項目的屬性。(反射是在運行時提供類型信息的技術。)
下麵的屏幕快照顯示了 PropertyGrid 在窗體上的外觀。
圖 1:窗體上的 PropertyGrid
PropertyGrid 包含以下部分:
- 屬性
- 可展開屬性
- 屬性類別標題
- 屬性說明
- 屬性編輯器
- 屬性選項卡
- 命令窗格(顯示控制項設計器提供的設計器操作)
創建 PropertyGrid 控制項
要使用 Visual Studio .NET 創建 PropertyGrid 控制項,需要將該控制項添加到工具箱中,因為預設情況下並不包含該控制項。在 Tools (工具)菜單中,選擇 Customize Toolbox (自定義工具箱)。在對話框中選擇 Framework Components (框架組件)選項卡,然後選擇 PropertyGrid 。
如果您從命令行編譯代碼,請使用 /reference 選項並指定 System.Windows.Forms.dll。
以下代碼顯示瞭如何創建 PropertyGrid 控制項並將其添加到窗體中。
[c-sharp] view plain copy
- using System;
- using System.Drawing;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Globalization;
- public class OptionsDialog : System.Windows.Forms.Form
- {
- private System.Windows.Forms.PropertyGrid OptionsPropertyGrid;
- public OptionsDialog()
- {
- OptionsPropertyGrid = new PropertyGrid();
- OptionsPropertyGrid.Size = new Size(300, 250);
- this.Controls.Add(OptionsPropertyGrid);
- this.Text = "選項對話框";
- }
- [STAThread]
- static void Main()
- {
- Application.Run(new OptionsDialog());
- }
- }
何處使用 PropertyGrid 控制項
在應用程式中的很多地方,您都可以使用戶與 PropertyGrid 進行交互,從而獲得更豐富的編輯體驗。例如,某個應用程式包含多個用戶可以設置的“設置”或選項,其中一些可能十分複雜。您可以使用單選按鈕、組合框或文本框來表示這些選項。但本文將逐步介紹如何使用 PropertyGrid 控制項創建選項視窗來設置應用程式選項。上面所創建的 OptionsDialog
窗體即是選項視窗的開始。現在,我們創建一個名為 AppSettings
的類,其中包含映射到應用程式設置的所有屬性。如果創建單獨的類而不使用多個分散的變數,設置將更便於管理和維護。
[c-sharp] view plain copy
- public class AppSettings{
- private bool saveOnClose = true;
- private string greetingText = "歡迎使用應用程式!";
- private int itemsInMRU = 4;
- private int maxRepeatRate = 10;
- private bool settingsChanged = false;
- private string appVersion = "1.0";
- public bool SaveOnClose
- {
- get { return saveOnClose; }
- set { saveOnClose = value;}
- }
- public string GreetingText
- {
- get { return greetingText; }
- set { greetingText = value; }
- }
- public int MaxRepeatRate
- {
- get { return maxRepeatRate; }
- set { maxRepeatRate = value; }
- }
- public int ItemsInMRUList
- {
- get { return itemsInMRU; }
- set { itemsInMRU = value; }
- }
- public bool SettingsChanged
- {
- get { return settingsChanged; }
- set { settingsChanged = value; }
- }
- public string AppVersion
- {
- get { return appVersion; }
- set { appVersion = value; }
- }
- }
選項視窗上的 PropertyGrid 將使用此類,因此請將類定義添加到應用程式項目中,在添加時可創建新文件或將其添加到現有窗體源代碼的下方。
選擇對象
要標識 PropertyGrid 顯示的內容,請將 PropertyGrid.SelectedObject 屬性設置為一個對象實例。然後,PropertyGrid 將完成其餘的工作。每次設置 SelectedObject 時,PropertyGrid 都會刷新顯示的屬性。這提供了一種簡單的方法來強制刷新屬性,或在運行時切換對象。您還可以調用 PropertyGrid.Refresh 方法來刷新屬性。
接下來,您需要更新 OptionsDialog
構造函數中的代碼,以創建一個 AppSettings
對象,並將其設置為PropertyGrid.SelectedObject 屬性的值。
[c-sharp] view plain copy
- public OptionsDialog()
- {
- OptionsPropertyGrid = new PropertyGrid();
- OptionsPropertyGrid.Size = new Size(300, 250);
- this.Controls.Add(OptionsPropertyGrid);
- this.Text = "選項對話框";
- // 創建 AppSettings 類併在 PropertyGrid 中顯示該類。
- AppSettings appset = new AppSettings();
- OptionsPropertyGrid.SelectedObject = appset;
- }
編譯並運行該應用程式。下麵的屏幕快照顯示了應用程式的外觀。
圖 2:PropertyGrid 中選定的 AppSettings 類
自定義 PropertyGrid 控制項
您可以修改 PropertyGrid 的某些外觀特征以滿足自己的需要。可以更改某些屬性的顯示方式,甚至選擇不顯示某些屬性。那麼,如何對 PropertyGrid 進行自定義呢?
更改 PropertyGrid 的外觀特征
PropertyGrid 的許多外觀特征都可以自定義。下麵列出了其中的一部分:
- 通過 HelpBackColor 、HelpForeColor 和 HelpVisible 屬性可以更改背景顏色、更改字體顏色或隱藏說明窗格。
- 通過 ToolbarVisible 屬性可以隱藏工具欄,通過 BackColor 屬性可以更改工具欄的顏色,通過LargeButtons 屬性可以顯示大工具欄按鈕。
- 使用 PropertySort 屬性可以按字母順序對屬性進行排序和分類。
- 通過 BackColor 屬性可以更改拆分器的顏色。
- 通過 LineColor 屬性可以更改網格線和邊框。
本示例中的選項視窗不需要工具欄,因此可以將 ToolbarVisible 設置為 false 。其餘屬性均保留預設設置。
更改屬性的顯示方式
要更改某些屬性的顯示方式,您可以對這些屬性應用不同的特性。特性是用於為類型、欄位、方法和屬性等編程元素添加批註的聲明標記,在運行時可以使用反射對其進行檢索。下麵列出了其中的一部分:
- DescriptionAttribute - 設置顯示在屬性下方說明幫助窗格中的屬性文本。這是一種為活動屬性(即具有焦點的屬性)提供幫助文本的有效方法。可以將此特性應用於
MaxRepeatRate
屬性。 - CategoryAttribute - 設置屬性在網格中所屬的類別。當您需要將屬性按類別名稱分組時,此特性非常有用。如果沒有為屬性指定類別,該屬性將被分配給雜項 類別。可以將此特性應用於所有屬性。
- BrowsableAttribute – 表示是否在網格中顯示屬性。此特性可用於在網格中隱藏屬性。預設情況下,公共屬性始終顯示在網格中。可以將此特性應用於
SettingsChanged
屬性。 - ReadOnlyAttribute – 表示屬性是否為只讀。此特性可用於禁止在網格中編輯屬性。預設情況下,帶有 get 和 set 訪問函數的公共屬性在網格中是可以編輯的。可以將此特性應用於
AppVersion
屬性。 - DefaultValueAttribute – 表示屬性的預設值。如果希望為屬性提供預設值,然後確定該屬性值是否與預設值相同,則可使用此特性。可以將此特性應用於所有屬性。
- DefaultPropertyAttribute – 表示類的預設屬性。在網格中選擇某個類時,將首先突出顯示該類的預設屬性。可以將此特性應用於
AppSettings
類。
現在,我們將其中的一些特性應用於 AppSettings
類,以更改屬性在 PropertyGrid 中的顯示方式。
[c-sharp] view plain copy
- [DefaultPropertyAttribute("SaveOnClose")]
- public class AppSettings{
- private bool saveOnClose = true;
- private string greetingText = "歡迎使用應用程式!";
- private int maxRepeatRate = 10;
- private int itemsInMRU = 4;
- private bool settingsChanged = false;
- private string appVersion = "1.0";
- [CategoryAttribute("文檔設置"),
- DefaultValueAttribute(true)]
- public bool SaveOnClose
- {
- get { return saveOnClose; }
- set { saveOnClose = value;}
- }
- [CategoryAttribute("全局設置"),
- ReadOnlyAttribute(true),
- DefaultValueAttribute("歡迎使用應用程式!")]
- public string GreetingText
- {
- get { return greetingText; }
- set { greetingText = value; }
- }
- [CategoryAttribute("全局設置"),
- DefaultValueAttribute(4)]
- public int ItemsInMRUList
- {
- get { return itemsInMRU; }
- set { itemsInMRU = value; }
- }
- [DescriptionAttribute("以毫秒錶示的文本重覆率。"),
- CategoryAttribute("全局設置"),
- DefaultValueAttribute(10)]
- public int MaxRepeatRate
- {
- get { return maxRepeatRate; }
- set { maxRepeatRate = value; }
- }
- [BrowsableAttribute(false),
- DefaultValueAttribute(false)]
- public bool SettingsChanged
- {
- get { return settingsChanged; }
- set { settingsChanged = value; }
- }
- [CategoryAttribute("版本"),
- DefaultValueAttribute("1.0"),
- ReadOnlyAttribute(true)]
- public string AppVersion
- {
- get { return appVersion; }
- set { appVersion = value; }
- }
- }
將這些特性應用於 AppSettings
類後,編譯並運行該應用程式。下麵的屏幕快照顯示了應用程式的外觀。
圖 3:PropertyGrid 中顯示的帶有類別和預設值的屬性
使用此版本的選項視窗後,您會註意到以下幾點:
- 顯示視窗時,將首先突出顯示
SaveOnClose
屬性。 - 選中
MaxRepeatRate
屬性時,說明幫助窗格中將顯示“以毫秒錶示的文本重覆率”。 SaveOnClose
屬性顯示在“文檔設置”類別下。其他屬性分別顯示在“全局設置”和“版本”類別下。SettingsChanged
屬性將不再顯示。AppVersion
屬性為只讀。只讀屬性以灰顯文本顯示。- 如果
SaveOnClose
屬性包含的值不是 true ,該值將以粗體顯示。PropertyGrid 使用粗體文本表示包含非預設值的屬性。
顯示覆雜屬性
到現在為止,選項視窗顯示的都是簡單的類型,如整數、布爾值和字元串。那麼,如何顯示更複雜的類型呢?如果應用程式需要跟蹤視窗大小、文檔字體或工具欄顏色等信息,該如何處理呢?.NET 框架提供的某些數據類型具有特殊的顯示功能,能使這些類型在 PropertyGrid 中更具可用性。
對所提供類型的支持
首先,請更新 AppSettings
類,為視窗大小(Size 類型)、視窗字體(Font 類型)和工具欄顏色(Color 類型)添加新屬性。
[c-sharp] view plain copy
- [DefaultPropertyAttribute("SaveOnClose")]
- public class AppSettings{
- private bool saveOnClose = true;
- private string greetingText = "歡迎使用應用程式!";
- private int maxRepeatRate = 10;
- private int itemsInMRU = 4;
- private bool settingsChanged = false;
- private string appVersion = "1.0";
- private Size windowSize = new Size(100,100);
- private Font windowFont = new Font("宋體", 9, FontStyle.Regular);
- private Color toolbarColor = SystemColors.Control;
- [CategoryAttribute("文檔設置"),
- DefaultValueAttribute(true)]
- public bool SaveOnClose
- {
- get { return saveOnClose; }
- set { saveOnClose = value;}
- }
- [CategoryAttribute("文檔設置")]
- public Size WindowSize
- {
- get { return windowSize; }
- set { windowSize = value;}
- }
- [CategoryAttribute("文檔設置")]
- public Font WindowFont
- {
- get {return windowFont; }
- set { windowFont = value;}
- }
- [CategoryAttribute("全局設置")]
- public Color ToolbarColor
- {
- get { return toolbarColor; }
- set { toolbarColor = value; }
- }
- [CategoryAttribute("全局設置"),
- ReadOnlyAttribute(true),
- DefaultValueAttribute("歡迎使用應用程式!")]
- public string GreetingText
- {
- get { return greetingText; }
- set { greetingText = value; }
- }
- [CategoryAttribute("全局設置"),
- DefaultValueAttribute(4)]
- public int ItemsInMRUList
- {
- get { return itemsInMRU; }
- set { itemsInMRU = value; }
- }
- [DescriptionAttribute("以毫秒錶示的文本重覆率。"),
- CategoryAttribute("全局設置"),
- DefaultValueAttribute(10)]
- public int MaxRepeatRate
- {
- get { return maxRepeatRate; }
- set { maxRepeatRate = value; }
- }
- [BrowsableAttribute(false),
- DefaultValueAttribute(false)]
- public bool SettingsChanged
- {
- get { return settingsChanged; }
- set { settingsChanged = value; }
- }
- [CategoryAttribute("版本"),
- DefaultValueAttribute("1.0"),
- ReadOnlyAttribute(true)]
- public string AppVersion
- {
- get { return appVersion; }
- set { appVersion = value; }
- }
- }
下麵的屏幕快照顯示了新屬性在 PropertyGrid 中的外觀。
圖 4:顯示在 PropertyGrid 中的 .NET 框架數據類型
請註意,WindowFont
屬性帶有一個省略號 (...) 按鈕,按下該按鈕將顯示字體選擇對話框。此外,還可以展開該屬性以顯示更多的 Font 屬性。某些 Font 屬性提供有關字體的值和詳細信息的下拉列表。您可以展開 WindowSize
屬性以顯示 Size 類型的更多屬性。最後,請註意,ToolbarColor
屬性包含一個選定顏色的樣本,以及一個用於選擇不同顏色的自定義下拉列表。對於這些以及其他數據類型,.NET 框架提供了其他的類,可以使在 PropertyGrid 中的編輯更加容易。
對自定義類型的支持
現在,您需要在 AppSettings
類中添加另外兩個屬性,即 DefaultFileName
和 SpellCheckOptions
。DefaultFileName
屬性用於獲取或設置字元串;SpellCheckOptions
屬性用於獲取或設置 SpellingOptions
類的實例。
SpellingOptions
類是一個新類,用於管理應用程式的拼寫檢查屬性。對於何時創建單獨的類以管理對象的屬性,並沒有嚴格的規定,而取決於您的整個類設計。將 SpellingOptions
類定義添加到應用程式項目中 - 可以添加到新文件中,也可以添加到窗體源代碼的下方。
[c-sharp] view plain copy
- [DescriptionAttribute("展開以查看應用程式的拼寫選項。")]
- public class SpellingOptions{
- private bool spellCheckWhileTyping = true;
- private bool spellCheckCAPS = false;
- private bool suggestCorrections = true;
- [DefaultValueAttribute(true)]
- public bool SpellCheckWhileTyping
- {
- get { return spellCheckWhileTyping; }
- set { spellCheckWhileTyping = value; }
- }
- [DefaultValueAttribute(false)]
- public bool SpellCheckCAPS
- {
- get { return spellCheckCAPS; }
- set { spellCheckCAPS = value; }
- }
- [DefaultValueAttribute(true)]
- public bool SuggestCorrections
- {
- get { return suggestCorrections; }
- set { suggestCorrections = value; }
- }
- }
再次編譯並運行選項視窗應用程式。下麵的屏幕快照顯示了應用程式的外觀。
圖 5:在 PropertyGrid 中顯示的不帶類型轉換器的自定義數據類型
請註意 SpellcheckOptions
屬性的外觀。與 .NET 框架類型不同,它不展開或顯示自定義的字元串表示。如果要在自己的複雜類型中提供與 .NET 框架類型相同的編輯體驗,該如何處理呢?.NET 框架類型使用 TypeConverter 和UITypeEditor 類提供大部分 PropertyGrid 編輯支持,您也可以使用這些類。
添加可展開屬性支持
要使 PropertyGrid 能夠展開 SpellingOptions
屬性,您需要創建 TypeConverter 。TypeConverter 提供了從一種類型轉換為另一種類型的方法。PropertyGrid 使用 TypeConverter 將對象類型轉換為 String ,並使用該String 在網格中顯示對象值。在編輯過程中,TypeConverter 會將 String 轉換回對象類型。.NET 框架提供的ExpandableObjectConverter 類可以簡化這一過程。
提供可展開對象支持
- 創建一個從 ExpandableObjectConverter 繼承而來的類。
[c-sharp] view plain copy- public class SpellingOptionsConverter:ExpandableObjectConverter
- { }
- 如果
destinationType
參數與使用此類型轉換器的類(示例中的SpellingOptions
類)的類型相同,則覆蓋CanConvertTo 方法並返回 true ;否則返回基類 CanConvertTo 方法的值。
[c-sharp] view plain copy- public override bool CanConvertTo(ITypeDescriptorContext context,
- System.Type destinationType)
- {
- if (destinationType == typeof(SpellingOptions))
- return true;
- return base.CanConvertTo(context, destinationType);
- }
- 覆蓋 ConvertTo 方法,並確保
destinationType
參數是一個 String ,並且值的類型與使用此類型轉換器的類(示例中的SpellingOptions
類)相同。如果其中任一情況為 false ,都將返回基類 ConvertTo 方法的值;否則,返回值對象的字元串表示。字元串表示需要使用唯一分隔符將類的每個屬性隔開。由於整個字元串都將顯示在 PropertyGrid 中,因此需要選擇一個不會影響可讀性的分隔符,逗號的效果通常比較好。
[c-sharp] view plain copy- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
- object value, System.Type destinationType)
- {
- if (destinationType == typeof(System.String) &&
- value is SpellingOptions){
- SpellingOptions so = (SpellingOptions)value;
- return "在鍵入時檢查:" + so.SpellCheckWhileTyping +
- ",檢查大小寫: " + so.SpellCheckCAPS +
- ",建議更正: " + so.SuggestCorrections;
- }
- return base.ConvertTo(context, culture, value, destinationType);
- }
- (可選)通過指定類型轉換器可以從字元串進行轉換,您可以啟用網格中對象字元串表示的編輯。要執行此操作,首先需要覆蓋 CanConvertFrom 方法並返回 true (如果源 Type 參數為 String 類型);否則,返回基類 CanConvertFrom 方法的值。
[c-sharp] view plain copy- public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
- {
- if (sourceType == typeof(string))
- return true;
- return base.CanConvertFrom(context, sourceType);
- }
- 要啟用對象基類的編輯,同樣需要覆蓋 ConvertFrom 方法並確保值參數是一個 String 。如果不是 String,將返回基類 ConvertFrom 方法的值;否則,返回基於值參數的類(示例中的
SpellingOptions
類)的新實例。您需要根據值參數解析類的每個屬性的值。瞭解在 ConvertTo 方法中創建的分隔字元串的格式將有助於您的解析。
[c-sharp] view plain copy- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- if (value is string) {
- try {
- string s = (string) value;
- int colon = s.IndexOf(':');
- int comma = s.IndexOf(',');
- if (colon != -1 && comma != -1) {
- string checkWhileTyping = s.Substring(colon + 1 , (comma - colon - 1));
- colon = s.IndexOf(':', comma + 1);
- comma = s.IndexOf(',', comma + 1);
- string checkCaps = s.Substring(colon + 1 , (comma - colon -1));
- colon = s.IndexOf(':', comma + 1);
- string suggCorr = s.Substring(colon + 1);
- SpellingOptions so = new SpellingOptions();
- so.SpellCheckWhileTyping =Boolean.Parse(checkWhileTyping);
- so.SpellCheckCAPS = Boolean.Parse(checkCaps);
- so.SuggestCorrections = Boolean.Parse(suggCorr);
- return so;
- }
- }
- catch {
- throw new ArgumentException(
- "無法將“" + (string)value +
- "”轉換為 SpellingOptions 類型");
- }
- }
- return base.ConvertFrom(context, culture, value);
- }
- 現在已經有了一個類型轉換器類,下麵您需要確定使用該類的目標類。您可以通過將TypeConverterAttribute 應用到目標類(示例中的
SpellingOptions
類)來執行此操作。
[c-sharp] view plain copy- // 應用於 SpellingOptions 類的 TypeConverter 特性。
- [TypeConverterAttribute(typeof(SpellingOptionsConverter)),
- DescriptionAttribute(“展開以查看應用程式的拼寫選項。")]
- public class SpellingOptions{ ... }
再次編譯並運行選項視窗應用程式。下麵的屏幕快照顯示了選項視窗目前的外觀。
圖 6:在 PropertyGrid 中顯示的帶有類型轉換器的自定義數據類型
註意: 如果只需要可展開對象支持,而不需要自定義字元串表示,則只需將TypeConverterAttribute 應用到類中。將 ExpandableObjectConverter 指定為類型轉換器類型。
添加域列表和簡單的下拉列表屬性支持
對於基於 Enum 類型返回枚舉的屬性,PropertyGrid 會自動在下拉列表中顯示枚舉值。EnumConverter 也提供了這一功能。對於自己的屬性,您可能希望為用戶提供一個有效值列表(有時也稱為選取列表或域列表),而其類型並不是基於 Enum 。如果域值在運行時之前未知,或者值可以更改,則屬於這種情況。
修改選項視窗,提供一個用戶可從中選擇的預設文件名的域列表。您已經將 DefaultFileName
屬性添加到AppSettings
類。下一步是在 PropertyGrid 中顯示屬性的下拉列表,以提供域列表。
提供簡單的下拉列表屬性支持
- 創建一個從類型轉換器類繼承而來的類。由於 DefaultFileName 屬性屬於 String 類型,因此可以從StringConverter 中繼承。如果屬性類型的類型轉換器不存在,則可以從 TypeConverter 繼承;這裡並不需要。
[c-sharp] view plain copy- public class FileNameConverter: StringConverter { }
- 覆蓋 GetStandardValuesSupported 方法並返回 true ,表示此對象支持可以從列表中選取的一組標準值。
[c-sharp] view plain copy- public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
- {
- return true;
- }
- 覆蓋 GetStandardValues 方法並返回填充了標準值的 StandardValuesCollection 。創建StandardValuesCollection 的方法之一是在構造函數中提供一個值數組。對於選項視窗應用程式,您可以使用填充了建議的預設文件名的 String 數組。
[c-sharp] view plain copy- public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
- {
- return new StandardValuesCollection(new string[]{"新文件", "文件1", "文檔1"});
- }
- (可選)如果希望用戶能夠鍵入下拉列表中沒有包含的值,請覆蓋 GetStandardValuesExclusive 方法並返回 false 。這從根本上將下拉列表樣式變成了組合框樣式。
[c-sharp] view plain copy- public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
- {
- return false;
- }
- 擁有自己的用於顯示下拉列表的類型轉換器類後,您需要確定使用該類的目標。在本示例中,目標為DefaultFileName 屬性,因為類型轉換器是針對該屬性的。將 TypeConverterAttribute 應用到目標屬性中。
[c-sharp] view plain copy- // 應用到 DefaultFileName 屬性的 TypeConverter 特性。
- [TypeConverter(typeof(FileNameConverter)),
- CategoryAttribute("文檔設置")]
- public string DefaultFileName
- {
- get{ return defaultFileName; }
- set{ defaultFileName = value; }
- }
再次編譯並運行選項視窗應用程式。下麵的屏幕快照顯示了選項視窗目前的外觀。請註意 DefaultFileName 屬性的外觀。
圖 7:在 PropertyGrid 中顯示下拉域列表
為屬性提供自定義 UI
如上所述,.NET 框架類型使用 TypeConverter 和 UITypeEditor 類(以及其他類)來提供 PropertyGrid 編輯支持。有關如何使用 TypeConverter ,請參閱對自定義類型的支持 一節;您也可以使用 UITypeEditor 類來自定義PropertyGrid 。
您可以在 PropertyGrid 中提供小圖形表示和屬性值,類似於為 Image 和 Color 類提供的內容。要在自定義中執行此操作,請從 UITypeEditor 繼承,覆蓋 GetPaintValueSupported 並返回 true 。然後,覆蓋UITypeEditor.PaintValue 方法,併在自己的方法中使用 PaintValueEventArgs. Graphics 參數繪製圖形。最後,將 Editor 特性應用到使用 UITypeEditor 類的類或屬性。
下麵的屏幕快照顯示了結果外觀。
圖 8:在 PropertyGrid 中顯示屬性的自定義圖形
您也可以提供自己的下拉列表控制項,這與 Control.Dock 屬性用來為用戶提供靠接選擇的控制項類似。要執行此操作,請從 UITypeEditor 繼承,覆蓋 GetEditStyle ,然後返回一個 UITypeEditorEditStyle 枚舉值,例如DropDown 。您的自定義下拉列表控制項必須從 Control 或 Control 的派生類(例如 UserControl )繼承而來。然後,覆蓋 UITypeEditor.EditValue 方法。使用 IServiceProvider 參數調用 IServiceProvider.GetService 方法,以獲取一個 IWindowsFormsEditorService 實例。最後,調用IWindowsFormsEditorService.DropDownControl 方法來顯示您的自定義下拉列表控制項。請記住將 Editor 特性應用到使用 UITypeEditor 類的類或屬性中。
下麵的屏幕快照顯示了結果外觀。
圖 9:在 PropertyGrid 中顯示屬性的自定義下拉列表控制項
除了使用 TypeEditor 和 UITypeEditor 類外,還可以自定義 PropertyGrid 以顯示其他屬性選項卡。屬性選項卡從PropertyTab 類繼承而來。如果您使用過 Microsoft Visual C#™ .NET 中的屬性瀏覽器,那麼就可能看到過自定義的 PropertyTab 。Events 選項卡(帶有閃電圖形的按鈕)就是一個自定義的 PropertyTab 。下麵的屏幕快照顯示了自定義 PropertyTab 的另一個示例。可以使用 PropertyTab 編輯按鈕的邊界點,以創建自定義的按鈕形狀。
圖 10:在 PropertyGrid 中顯示自定義選項卡
如果想在item中增加自定義的顯示方式,比如日期選擇啦、下拉框啦、甚至文件選擇、拾色器等等,我們可以參考如下:
改變 PropertyGrid 控制項的編輯風格(1)加入日期控制項
編輯日期類型數據
[c-sharp] view plain copy
- using System;
- using System.Windows.Forms;
- using System.Drawing.Design;
- using System.Windows.Forms.Design;
- namespace blog.csdn.net.zhangyuk
- {
- /// <summary>
- /// 在PropertyGrid 上顯示日期控制項
- /// </summary>
- public class PropertyGridDateItem : UITypeEditor
- {
- MonthCalendar dateControl = new MonthCalendar();
- public PropertyGridDateItem()
- {
- dateControl.MaxSelectionCount = 1;
- }
- public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
- {
-