C# PropertyGrid控制項應用心得(轉載)

来源:http://www.cnblogs.com/tooyeah/archive/2016/10/19/5976255.html
-Advertisement-
Play Games

最近項目中做一模塊時偶發奇想,希望使用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  
  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 類可以簡化這一過程。

提供可展開對象支持

  1. 創建一個從 ExpandableObjectConverter 繼承而來的類。 
    [c-sharp] view plain copy  
    1. public class SpellingOptionsConverter:ExpandableObjectConverter   
    2. {   }  
  2. 如果 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. }  
  3. 覆蓋 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. }  
  4. (可選)通過指定類型轉換器可以從字元串進行轉換,您可以啟用網格中對象字元串表示的編輯。要執行此操作,首先需要覆蓋 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. }  
  5. 要啟用對象基類的編輯,同樣需要覆蓋 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. }  
  6. 現在已經有了一個類型轉換器類,下麵您需要確定使用該類的目標類。您可以通過將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 中顯示屬性的下拉列表,以提供域列表。

 

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

  1. 創建一個從類型轉換器類繼承而來的類。由於 DefaultFileName 屬性屬於 String 類型,因此可以從StringConverter 中繼承。如果屬性類型的類型轉換器不存在,則可以從 TypeConverter 繼承;這裡並不需要。

    [c-sharp] view plain copy  
    1. public class FileNameConverter: StringConverter {   }  
  2. 覆蓋 GetStandardValuesSupported 方法並返回 true ,表示此對象支持可以從列表中選取的一組標準值。   
    [c-sharp] view plain copy  
    1. public override bool GetStandardValuesSupported(ITypeDescriptorContext context)  
    2. {  
    3.     return true;  
    4. }  
  3. 覆蓋 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. }   
  4. (可選)如果希望用戶能夠鍵入下拉列表中沒有包含的值,請覆蓋 GetStandardValuesExclusive 方法並返回 false 。這從根本上將下拉列表樣式變成了組合框樣式。
    [c-sharp] view plain copy  
    1. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)  
    2. {  
    3.     return false;  
    4. }  
  5. 擁有自己的用於顯示下拉列表的類型轉換器類後,您需要確定使用該類的目標。在本示例中,目標為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)加入日期控制項

編輯日期類型數據

 

[c-sharp] view plain copy  
  1. using System;  
  2.   
  3. using System.Windows.Forms;  
  4.   
  5. using System.Drawing.Design;  
  6.   
  7. using System.Windows.Forms.Design;  
  8.   
  9. namespace blog.csdn.net.zhangyuk  
  10.   
  11. {  
  12.   
  13.     /// <summary>  
  14.   
  15.     /// 在PropertyGrid 上顯示日期控制項   
  16.   
  17.     /// </summary>  
  18.   
  19.     public class PropertyGridDateItem : UITypeEditor  
  20.   
  21.     {  
  22.   
  23.         MonthCalendar dateControl = new MonthCalendar();  
  24.   
  25.         public PropertyGridDateItem()  
  26.   
  27.         {  
  28.   
  29.             dateControl.MaxSelectionCount = 1;  
  30.   
  31.         }  
  32.   
  33.         public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)  
  34.   
  35.         {  
  36.   
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在.NET的項目中,有時候需要獲取電腦的硬體的相關信息,在C#語言中需要利用ManagementClass這個類來進行相關操作。 現在先來介紹一下ManagementClass類,首先看一下類的繼承結構: 現在看一下MSDN對ManagementClass類的解釋,對錶示一個通用信息模型 (CIM ...
  • 今天打包程式時突然發現InstallShield居然報錯ISEXP : error : -6003: An error occurred streaming 'D:\Program Files (x86)\InstallShield\2015LE\SetupPrerequisites\Windows ...
  • 在基類中聲明可以從派生類引發的事件的標準方法。此模式廣泛應用於.Net Framework類庫中的Windows窗體類。 我們來看一個Button類的定義 我們通過ButtonBase最後找到基類Control 在包含事件的基類中創建一個受保護的調用方法。通過調用或重寫方法,派生類便可以間接調用該事 ...
  • 在很多情況下,我們網站可能會展示我們的產品圖片、以及教程視頻等內容,結合一個比較好的圖片、視頻展示插件,能夠使得我們的站點更加方便使用,也更加酷炫,在Github上有很多相關的處理插件可以找來使用,有些效果還非常好,本篇介紹使用圖片視頻展示插件blueimp Gallery改造網站的視頻圖片展示,並... ...
  • 1.1、Web Service基本概念 Web Service也叫XML Web Service WebService是一種可以接收從Internet或者Intranet上的其它系統中傳遞過來的請求,輕量級的獨立的通訊技術。是:通過SOAP在Web上提供的軟體服務,使用WSDL文件進行說明,並通過U ...
  • 解決方法: 已經整理好包: https://pan.baidu.com/s/1dFuU80p 下載解壓運行: DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe 現象: (前幾天安裝的時候沒有截圖,下麵這圖片從網路上引用) Setup Failed 0x800 ...
  • 談到HTTP協議(超文本傳輸協議),HTTP協議是一個基於請求與響應模式的、無狀態的、應用層的協議,常基於TCP的連接方式,HTTP1.1版本中給出一種持續連接的機制,絕大多數的Web開發,都是構建在HTTP協議之上的Web應用。 HTTP是一個屬於應用層的面向對象的協議,由於其簡捷、快速的方式,適 ...
  • 我們通過System.Environment.OSVersion.Version獲得操作系統的版本號,然後再根據版本號進行判斷操作系統是什麼版本 Version 類的屬性 參考於:https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms7 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...