程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> C# PropertyGrid控件應用心得(轉載),

C# PropertyGrid控件應用心得(轉載),

編輯:關於.NET

C# PropertyGrid控件應用心得(轉載),


最近項目中做一模塊時偶發奇想,希望使用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  
  1. using System;  
  2. using System.Drawing;  
  3. using System.ComponentModel;  
  4. using System.Windows.Forms;  
  5. using System.Globalization;  
  6. public class OptionsDialog : System.Windows.Forms.Form  
  7. {  
  8.     private System.Windows.Forms.PropertyGrid OptionsPropertyGrid;  
  9.     public OptionsDialog()  
  10.     {  
  11.        OptionsPropertyGrid = new PropertyGrid();  
  12.        OptionsPropertyGrid.Size = new Size(300, 250);  
  13.        this.Controls.Add(OptionsPropertyGrid);  
  14.        this.Text = "選項對話框";  
  15.     }  
  16.     [STAThread]  
  17.     static void Main()  
  18.     {  
  19.        Application.Run(new OptionsDialog());  
  20.     }  
  21. }  


何處使用 PropertyGrid 控件 
在應用程序中的很多地方,您都可以使用戶與 PropertyGrid 進行交互,從而獲得更豐富的編輯體驗。例如,某個應用程序包含多個用戶可以設置的“設置”或選項,其中一些可能十分復雜。您可以使用單選按鈕、組合框或文本框來表示這些選項。但本文將逐步介紹如何使用 PropertyGrid 控件創建選項窗口來設置應用程序選項。上面所創建的 OptionsDialog 窗體即是選項窗口的開始。現在,我們創建一個名為 AppSettings 的類,其中包含映射到應用程序設置的所有屬性。如果創建單獨的類而不使用多個分散的變量,設置將更便於管理和維護。

 

 

[c-sharp] view plain copy  
  1. public class AppSettings{  
  2.      private bool saveOnClose = true;  
  3.      private string greetingText = "歡迎使用應用程序!";  
  4.      private int itemsInMRU = 4;  
  5.      private int maxRepeatRate = 10;  
  6.      private bool settingsChanged = false;  
  7.      private string appVersion = "1.0";  
  8.       
  9.      public bool SaveOnClose  
  10.      {  
  11.          get { return saveOnClose; }  
  12.          set { saveOnClose = value;}  
  13.      }  
  14.      public string GreetingText  
  15.      {  
  16.          get { return greetingText; }  
  17.          set { greetingText = value; }  
  18.      }  
  19.      public int MaxRepeatRate  
  20.      {  
  21.          get { return maxRepeatRate; }  
  22.          set { maxRepeatRate = value; }  
  23.      }  
  24.      public int ItemsInMRUList  
  25.      {  
  26.          get { return itemsInMRU; }  
  27.          set { itemsInMRU = value; }  
  28.      }  
  29.      public bool SettingsChanged  
  30.      {  
  31.          get { return settingsChanged; }  
  32.          set { settingsChanged = value; }  
  33.      }  
  34.      public string AppVersion  
  35.      {  
  36.          get { return appVersion; }  
  37.          set { appVersion = value; }  
  38.      }  
  39. }  

 

選項窗口上的 PropertyGrid 將使用此類,因此請將類定義添加到應用程序項目中,在添加時可創建新文件或將其添加到現有窗體源代碼的下方。

選擇對象

要標識 PropertyGrid 顯示的內容,請將 PropertyGrid.SelectedObject 屬性設置為一個對象實例。然後,PropertyGrid 將完成其余的工作。每次設置 SelectedObject 時,PropertyGrid 都會刷新顯示的屬性。這提供了一種簡單的方法來強制刷新屬性,或在運行時切換對象。您還可以調用 PropertyGrid.Refresh 方法來刷新屬性。

接下來,您需要更新 OptionsDialog 構造函數中的代碼,以創建一個 AppSettings 對象,並將其設置為PropertyGrid.SelectedObject 屬性的值。

 

[c-sharp] view plain copy  
  1. public OptionsDialog()  
  2. {  
  3.     OptionsPropertyGrid = new PropertyGrid();  
  4.     OptionsPropertyGrid.Size = new Size(300, 250);  
  5.     this.Controls.Add(OptionsPropertyGrid);  
  6.     this.Text = "選項對話框";  
  7.     // 創建 AppSettings 類並在 PropertyGrid 中顯示該類。  
  8.     AppSettings appset = new AppSettings();  
  9.     OptionsPropertyGrid.SelectedObject = appset;  
  10. }  

 

編譯並運行該應用程序。下面的屏幕快照顯示了應用程序的外觀。

 

圖 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  
  1. [DefaultPropertyAttribute("SaveOnClose")]  
  2. public class AppSettings{  
  3.      private bool saveOnClose = true;  
  4.      private string greetingText = "歡迎使用應用程序!";  
  5.      private int maxRepeatRate = 10;  
  6.      private int itemsInMRU = 4;  
  7.      private bool settingsChanged = false;  
  8.      private string appVersion = "1.0";  
  9.      [CategoryAttribute("文檔設置"),  
  10.      DefaultValueAttribute(true)]  
  11.      public bool SaveOnClose  
  12.      {  
  13.          get { return saveOnClose; }  
  14.          set { saveOnClose = value;}  
  15.      }  
  16.      [CategoryAttribute("全局設置"),  
  17.      ReadOnlyAttribute(true),  
  18.      DefaultValueAttribute("歡迎使用應用程序!")]  
  19.      public string GreetingText  
  20.      {  
  21.          get { return greetingText; }  
  22.          set { greetingText = value; }  
  23.      }  
  24.      [CategoryAttribute("全局設置"),  
  25.      DefaultValueAttribute(4)]  
  26.      public int ItemsInMRUList  
  27.      {  
  28.          get { return itemsInMRU; }  
  29.          set { itemsInMRU = value; }  
  30.      }  
  31.      [DescriptionAttribute("以毫秒表示的文本重復率。"),  
  32.      CategoryAttribute("全局設置"),  
  33.      DefaultValueAttribute(10)]  
  34.      public int MaxRepeatRate  
  35.      {  
  36.          get { return maxRepeatRate; }  
  37.          set { maxRepeatRate = value; }  
  38.      }  
  39.      [BrowsableAttribute(false),  
  40.      DefaultValueAttribute(false)]  
  41.      public bool SettingsChanged  
  42.      {  
  43.          get { return settingsChanged; }  
  44.          set { settingsChanged = value; }  
  45.      }  
  46.      [CategoryAttribute("版本"),  
  47.      DefaultValueAttribute("1.0"),  
  48.      ReadOnlyAttribute(true)]  
  49.      public string AppVersion  
  50.      {  
  51.          get { return appVersion; }  
  52.          set { appVersion = value; }  
  53.      }  
  54. }  

 

將這些特性應用於 AppSettings 類後,編譯並運行該應用程序。下面的屏幕快照顯示了應用程序的外觀。

 

圖 3:PropertyGrid 中顯示的帶有類別和默認值的屬性

使用此版本的選項窗口後,您會注意到以下幾點:

  • 顯示窗口時,將首先突出顯示 SaveOnClose 屬性。
  • 選中 MaxRepeatRate 屬性時,說明幫助窗格中將顯示“以毫秒表示的文本重復率”。
  • SaveOnClose 屬性顯示在“文檔設置”類別下。其他屬性分別顯示在“全局設置”和“版本”類別下。
  • SettingsChanged 屬性將不再顯示。
  • AppVersion 屬性為只讀。只讀屬性以灰顯文本顯示。
  • 如果 SaveOnClose 屬性包含的值不是 true ,該值將以粗體顯示。PropertyGrid 使用粗體文本表示包含非默認值的屬性。

顯示復雜屬性

到現在為止,選項窗口顯示的都是簡單的類型,如整數、布爾值和字符串。那麼,如何顯示更復雜的類型呢?如果應用程序需要跟蹤窗口大小、文檔字體或工具欄顏色等信息,該如何處理呢?.NET 框架提供的某些數據類型具有特殊的顯示功能,能使這些類型在 PropertyGrid 中更具可用性。

對所提供類型的支持 
首先,請更新 AppSettings 類,為窗口大小(Size 類型)、窗口字體(Font 類型)和工具欄顏色(Color 類型)添加新屬性。

 

[c-sharp] view plain copy  
  1. [DefaultPropertyAttribute("SaveOnClose")]  
  2. public class AppSettings{  
  3.      private bool saveOnClose = true;  
  4.      private string greetingText = "歡迎使用應用程序!";  
  5.      private int maxRepeatRate = 10;  
  6.      private int itemsInMRU = 4;  
  7.      private bool settingsChanged = false;  
  8.      private string appVersion = "1.0";  
  9.        
  10.      private Size windowSize = new Size(100,100);  
  11.      private Font windowFont = new Font("宋體", 9, FontStyle.Regular);  
  12.      private Color toolbarColor = SystemColors.Control;  
  13.      [CategoryAttribute("文檔設置"),  
  14.      DefaultValueAttribute(true)]  
  15.      public bool SaveOnClose  
  16.      {  
  17.          get { return saveOnClose; }  
  18.          set { saveOnClose = value;}  
  19.      }  
  20.      [CategoryAttribute("文檔設置")]  
  21.      public Size WindowSize   
  22.      {  
  23.          get { return windowSize; }  
  24.          set { windowSize = value;}  
  25.      }  
  26.      [CategoryAttribute("文檔設置")]  
  27.      public Font WindowFont   
  28.      {  
  29.          get {return windowFont; }  
  30.          set { windowFont = value;}  
  31.      }  
  32.      [CategoryAttribute("全局設置")]  
  33.      public Color ToolbarColor  
  34.      {  
  35.          get { return toolbarColor; }  
  36.          set { toolbarColor = value; }  
  37.      }  
  38.      [CategoryAttribute("全局設置"),  
  39.      ReadOnlyAttribute(true),  
  40.      DefaultValueAttribute("歡迎使用應用程序!")]  
  41.      public string GreetingText  
  42.      {  
  43.          get { return greetingText; }  
  44.          set { greetingText = value; }  
  45.      }  
  46.      [CategoryAttribute("全局設置"),  
  47.      DefaultValueAttribute(4)]  
  48.      public int ItemsInMRUList  
  49.      {  
  50.          get { return itemsInMRU; }  
  51.          set { itemsInMRU = value; }  
  52.      }  
  53.      [DescriptionAttribute("以毫秒表示的文本重復率。"),  
  54.      CategoryAttribute("全局設置"),  
  55.      DefaultValueAttribute(10)]  
  56.      public int MaxRepeatRate  
  57.      {  
  58.          get { return maxRepeatRate; }  
  59.          set { maxRepeatRate = value; }  
  60.      }  
  61.      [BrowsableAttribute(false),  
  62.      DefaultValueAttribute(false)]  
  63.      public bool SettingsChanged  
  64.      {  
  65.          get { return settingsChanged; }  
  66.          set { settingsChanged = value; }  
  67.      }  
  68.      [CategoryAttribute("版本"),  
  69.      DefaultValueAttribute("1.0"),  
  70.      ReadOnlyAttribute(true)]  
  71.      public string AppVersion  
  72.      {  
  73.          get { return appVersion; }  
  74.          set { appVersion = value; }  
  75.      }  
  76. }  

 

下面的屏幕快照顯示了新屬性在 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  
  1. [DescriptionAttribute("展開以查看應用程序的拼寫選項。")]  
  2. public class SpellingOptions{  
  3.      private bool spellCheckWhileTyping = true;  
  4.      private bool spellCheckCAPS = false;  
  5.      private bool suggestCorrections = true;  
  6.      [DefaultValueAttribute(true)]  
  7.      public bool SpellCheckWhileTyping   
  8.      {  
  9.          get { return spellCheckWhileTyping; }  
  10.          set { spellCheckWhileTyping = value; }  
  11.      }  
  12.      [DefaultValueAttribute(false)]  
  13.      public bool SpellCheckCAPS   
  14.      {  
  15.          get { return spellCheckCAPS; }  
  16.          set { spellCheckCAPS = value; }  
  17.      }  
  18.      [DefaultValueAttribute(true)]  
  19.      public bool SuggestCorrections   
  20.      {  
  21.          get { return suggestCorrections; }  
  22.          set { suggestCorrections = value; }  
  23.      }  
  24. }  

 

再次編譯並運行選項窗口應用程序。下面的屏幕快照顯示了應用程序的外觀。

 

圖 5:在 PropertyGrid 中顯示的不帶類型轉換器的自定義數據類型

請注意 SpellcheckOptions 屬性的外觀。與 .NET 框架類型不同,它不展開或顯示自定義的字符串表示。如果要在自己的復雜類型中提供與 .NET 框架類型相同的編輯體驗,該如何處理呢?.NET 框架類型使用 TypeConverter 和UITypeEditor 類提供大部分 PropertyGrid 編輯支持,您也可以使用這些類。

添加可展開屬性支持

要使 PropertyGrid 能夠展開 SpellingOptions 屬性,您需要創建 TypeConverter 。TypeConverter 提供了從一種類型轉換為另一種類型的方法。PropertyGrid 使用 TypeConverter 將對象類型轉換為 String ,並使用該String 在網格中顯示對象值。在編輯過程中,TypeConverter 會將 String 轉換回對象類型。.NET 框架提供的ExpandableObjectConverter 類可以簡化這一過程。

提供可展開對象支持

  • 如果 destinationType 參數與使用此類型轉換器的類(示例中的 SpellingOptions 類)的類型相同,則覆蓋CanConvertTo 方法並返回 true ;否則返回基類 CanConvertTo 方法的值。 
    [c-sharp] view plain copy  
    1. public override bool CanConvertTo(ITypeDescriptorContext context,  
    2.                                    System.Type destinationType)   
    3. {  
    4.      if (destinationType == typeof(SpellingOptions))  
    5.          return true;  
    6.      return base.CanConvertTo(context, destinationType);  
    7. }  
  • 覆蓋 ConvertTo 方法,並確保 destinationType 參數是一個 String ,並且值的類型與使用此類型轉換器的類(示例中的 SpellingOptions 類)相同。如果其中任一情況為 false ,都將返回基類 ConvertTo 方法的值;否則,返回值對象的字符串表示。字符串表示需要使用唯一分隔符將類的每個屬性隔開。由於整個字符串都將顯示在 PropertyGrid 中,因此需要選擇一個不會影響可讀性的分隔符,逗號的效果通常比較好。 
    [c-sharp] view plain copy  
    1. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,  
    2.     object value, System.Type destinationType)   
    3. {  
    4.      if (destinationType == typeof(System.String) &&   
    5.           value is SpellingOptions){  
    6.          SpellingOptions so = (SpellingOptions)value;  
    7.          return "在鍵入時檢查:" + so.SpellCheckWhileTyping +   
    8.                 ",檢查大小寫: " + so.SpellCheckCAPS +  
    9.                 ",建議更正: " + so.SuggestCorrections;  
    10.      }  
    11.      return base.ConvertTo(context, culture, value, destinationType);  
    12. }  
  • (可選)通過指定類型轉換器可以從字符串進行轉換,您可以啟用網格中對象字符串表示的編輯。要執行此操作,首先需要覆蓋 CanConvertFrom 方法並返回 true (如果源 Type 參數為 String 類型);否則,返回基類 CanConvertFrom 方法的值。 
    [c-sharp] view plain copy  
    1. public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)   
    2. {  
    3.      if (sourceType == typeof(string))  
    4.          return true;  
    5.      return base.CanConvertFrom(context, sourceType);  
    6. }  
  • 要啟用對象基類的編輯,同樣需要覆蓋 ConvertFrom 方法並確保值參數是一個 String 。如果不是 String,將返回基類 ConvertFrom 方法的值;否則,返回基於值參數的類(示例中的 SpellingOptions 類)的新實例。您需要根據值參數解析類的每個屬性的值。了解在 ConvertTo 方法中創建的分隔字符串的格式將有助於您的解析。 
    [c-sharp] view plain copy  
    1. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)   
    2. {  
    3.      if (value is string) {  
    4.          try {  
    5.              string s = (string) value;  
    6.              int colon = s.IndexOf(':');  
    7.              int comma = s.IndexOf(',');  
    8.              if (colon != -1 && comma != -1) {  
    9.                  string checkWhileTyping = s.Substring(colon + 1 , (comma - colon - 1));  
    10.                  colon = s.IndexOf(':', comma + 1);  
    11.                  comma = s.IndexOf(',', comma + 1);  
    12.                  string checkCaps = s.Substring(colon + 1 , (comma - colon -1));  
    13.                  colon = s.IndexOf(':', comma + 1);  
    14.                  string suggCorr = s.Substring(colon + 1);  
    15.                  SpellingOptions so = new SpellingOptions();  
    16.                  so.SpellCheckWhileTyping =Boolean.Parse(checkWhileTyping);  
    17.                  so.SpellCheckCAPS = Boolean.Parse(checkCaps);  
    18.                  so.SuggestCorrections = Boolean.Parse(suggCorr);  
    19.                  return so;  
    20.              }  
    21.          }  
    22.          catch {  
    23.              throw new ArgumentException(  
    24.                  "無法將“" + (string)value +   
    25.                                     "”轉換為 SpellingOptions 類型");  
    26.          }  
    27.      }     
    28.      return base.ConvertFrom(context, culture, value);  
    29. }  
  • 現在已經有了一個類型轉換器類,下面您需要確定使用該類的目標類。您可以通過將TypeConverterAttribute 應用到目標類(示例中的 SpellingOptions 類)來執行此操作。 
    [c-sharp] view plain copy  
    1. // 應用於 SpellingOptions 類的 TypeConverter 特性。  
    2. [TypeConverterAttribute(typeof(SpellingOptionsConverter)),  
    3. DescriptionAttribute(“展開以查看應用程序的拼寫選項。")]  
    4. public class SpellingOptions{ ... }  
  • 再次編譯並運行選項窗口應用程序。下面的屏幕快照顯示了選項窗口目前的外觀。

     

    圖 6:在 PropertyGrid 中顯示的帶有類型轉換器的自定義數據類型

    注意: 如果只需要可展開對象支持,而不需要自定義字符串表示,則只需將TypeConverterAttribute 應用到類中。將 ExpandableObjectConverter 指定為類型轉換器類型。

    添加域列表和簡單的下拉列表屬性支持

    對於基於 Enum 類型返回枚舉的屬性,PropertyGrid 會自動在下拉列表中顯示枚舉值。EnumConverter 也提供了這一功能。對於自己的屬性,您可能希望為用戶提供一個有效值列表(有時也稱為選取列表或域列表),而其類型並不是基於 Enum 。如果域值在運行時之前未知,或者值可以更改,則屬於這種情況。

    修改選項窗口,提供一個用戶可從中選擇的默認文件名的域列表。您已經將 DefaultFileName 屬性添加到AppSettings 類。下一步是在 PropertyGrid 中顯示屬性的下拉列表,以提供域列表。

     

    提供簡單的下拉列表屬性支持

  • 覆蓋 GetStandardValuesSupported 方法並返回 true ,表示此對象支持可以從列表中選取的一組標准值。   
    [c-sharp] view plain copy  
    1. public override bool GetStandardValuesSupported(ITypeDescriptorContext context)  
    2. {  
    3.     return true;  
    4. }  
  • 覆蓋 GetStandardValues 方法並返回填充了標准值的 StandardValuesCollection 。創建StandardValuesCollection 的方法之一是在構造函數中提供一個值數組。對於選項窗口應用程序,您可以使用填充了建議的默認文件名的 String 數組。   
    [c-sharp] view plain copy  
    1. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)  
    2. {  
    3.     return new StandardValuesCollection(new string[]{"新文件", "文件1", "文檔1"});  
    4. }   
  • (可選)如果希望用戶能夠鍵入下拉列表中沒有包含的值,請覆蓋 GetStandardValuesExclusive 方法並返回 false 。這從根本上將下拉列表樣式變成了組合框樣式。
    [c-sharp] view plain copy  
    1. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)  
    2. {  
    3.     return false;  
    4. }  
  • 擁有自己的用於顯示下拉列表的類型轉換器類後,您需要確定使用該類的目標。在本示例中,目標為DefaultFileName 屬性,因為類型轉換器是針對該屬性的。將 TypeConverterAttribute 應用到目標屬性中。
    [c-sharp] view plain copy  
    1. // 應用到 DefaultFileName 屬性的 TypeConverter 特性。  
    2. [TypeConverter(typeof(FileNameConverter)),  
    3. CategoryAttribute("文檔設置")]  
    4. public string DefaultFileName  
    5. {  
    6.     get{ return defaultFileName; }  
    7.     set{ defaultFileName = value; }  
    8. }  
  • 再次編譯並運行選項窗口應用程序。下面的屏幕快照顯示了選項窗口目前的外觀。請注意 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)加入日期控件

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved