C# PropertyGrid控件应用心得

原文:http://blog.csdn.net/zzh87615/article/details/6027552

目录
PropertyGrid 控件简介 
创建 PropertyGrid 控件 
何处使用 PropertyGrid 控件 
选择对象 
自定义 PropertyGrid 控件 
显示复杂属性 
为属性提供自定义 UI


PropertyGrid 控件简介

如果您使用过 Microsoft? Visual Basic? 或 Microsoft Visual Studio .NET,那么您一定使用过属性浏览器来浏览、查看和编辑一个或多个对象的属性。.NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心。PropertyGrid 控件显示对象或类型的属性,并主要通过使用反射来检索项目的属性。(反射是在运行时提供类型信息的技术。)

下面的屏幕快照显示了 PropertyGrid 在窗体上的外观。

Form1

PropertyGrid 包含以下部分:

  • 属性
  • 可展开属性
  • 属性类别标题
  • 属性说明
  • 属性编辑器
  • 属性选项卡
  • 命令窗格(显示控件设计器提供的设计器操作) 

创建 PropertyGrid 控件

要使用 Visual Studio .NET 创建 PropertyGrid 控件,需要将该控件添加到工具箱中,因为默认情况下并不包含该控件。在 Tools (工具)菜单中,选择 Customize Toolbox (自定义工具箱)。在对话框中选择Framework Components (框架组件)选项卡,然后选择 PropertyGrid 。

如果您从命令行编译代码,请使用 /reference 选项并指定 System.Windows.Forms.dll。

以下代码显示了如何创建 PropertyGrid 控件并将其添加到窗体中。

[c-sharp] view plaincopy
  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. }    
  22. using System;  
  23. using System.Drawing;  
  24. using System.ComponentModel;  
  25. using System.Windows.Forms;  
  26. using System.Globalization;  
  27. public class OptionsDialog : System.Windows.Forms.Form  
  28. {  
  29.     private System.Windows.Forms.PropertyGrid OptionsPropertyGrid;  
  30.     public OptionsDialog()  
  31.     {  
  32.        OptionsPropertyGrid = new PropertyGrid();  
  33.        OptionsPropertyGrid.Size = new Size(300, 250);  
  34.        this.Controls.Add(OptionsPropertyGrid);  
  35.        this.Text = "选项对话框";  
  36.     }  
  37.     [STAThread]  
  38.     static void Main()  
  39.     {  
  40.        Application.Run(new OptionsDialog());  
  41.     }  
  42. }   

何处使用 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. }    
  11. public OptionsDialog()  
  12. {  
  13.     OptionsPropertyGrid = new PropertyGrid();  
  14.     OptionsPropertyGrid.Size = new Size(300, 250);  
  15.     this.Controls.Add(OptionsPropertyGrid);  
  16.     this.Text = "选项对话框";  
  17.     // 创建 AppSettings 类并在 PropertyGrid 中显示该类。  
  18.     AppSettings appset = new AppSettings();  
  19.     OptionsPropertyGrid.SelectedObject = appset;  
  20. }   

编译并运行该应用程序。下面的屏幕快照显示了应用程序的外观。

 PropertyGrid 中选定的 AppSettings 类

图 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 类后,编译并运行该应用程序。下面的屏幕快照显示了应用程序的外观。

 PropertyGrid 中显示的带有类别和默认值的属性

图 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 中的外观。

 

显示在 PropertyGrid 中的 .NET 框架数据类型

图 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.   
  3.  public class SpellingOptions{     
  4.      private bool spellCheckWhileTyping = true;     
  5.      private bool spellCheckCAPS = false;     
  6.      private bool suggestCorrections = true;     
  7.      [DefaultValueAttribute(true)]     
  8.      public bool SpellCheckWhileTyping      
  9.      {     
  10.          get { return spellCheckWhileTyping; }     
  11.          set { spellCheckWhileTyping = value; }     
  12.      }     
  13.      [DefaultValueAttribute(false)]     
  14.      public bool SpellCheckCAPS      
  15.      {     
  16.          get { return spellCheckCAPS; }     
  17.          set { spellCheckCAPS = value; }     
  18.      }     
  19.      [DefaultValueAttribute(true)]     
  20.      public bool SuggestCorrections      
  21.      {     
  22.          get { return suggestCorrections; }     
  23.          set { suggestCorrections = value; }     
  24.      }     
  25. }    

再次编译并运行选项窗口应用程序。下面的屏幕快照显示了应用程序的外观。

 在 PropertyGrid 中显示的不带类型转换器的自定义数据类型

图 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. }    
  7. public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)   
  8. {  
  9.      if (sourceType == typeof(string))  
  10.          return true;  
  11.      return base.CanConvertFrom(context, sourceType);  
  12. }   

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 类)来执行此操作。 
// 应用于 SpellingOptions 类的 TypeConverter 特性。
[TypeConverterAttribute(typeof(SpellingOptionsConverter)),
DescriptionAttribute(“展开以查看应用程序的拼写选项。")]
public class SpellingOptions{ ... } 
再次编译并运行选项窗口应用程序。下面的屏幕快照显示了选项窗口目前的外观。

 在 PropertyGrid 中显示的带有类型转换器的自定义数据类型

图 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.     getreturn defaultFileName; }  
  7.     set{ defaultFileName = value; }  
  8. }   

再次编译并运行选项窗口应用程序。下面的屏幕快照显示了选项窗口目前的外观。请注意 DefaultFileName 属性的外观。

 在 PropertyGrid 中显示下拉域列表

图 7:在 PropertyGrid 中显示下拉域列表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值