C#PropertyGrid所有用法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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控件并将其添加到窗体中。

ing System;
ing System.Drawing;
ing ponentModel;
ing System.Windows.Forms;
ing 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()
19.Application.Run(new OptionsDialog());
20.}
21.}
何处使用 PropertyGrid 控件
在应用程序中的很多地方,您都可以使用户与PropertyGrid进行交互,从而获得更丰富的编辑体验。

例如,某个应用程序包含多个用户可以设置的“设置”或选项,其中一些可能十分复杂。

您可以使用单选按钮、组合框或文本框来表示这些选项。

但本文将逐步介绍如何使用PropertyGrid控件创建选项窗口来设置应用程序选项。

上面所创建的OptionsDialog 窗体即是选项窗口的开始。

现在,我们创建一个名为AppSettings 的类,其中包含映射到应用程序设置的所有属性。

如果创建单独的类而不使用多个分散的变量,设置将更便于管理和维护。

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; }
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属性的值。

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中的显示方式。

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 类型)添加新属性。

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 类定义添加到应用程序项目中 - 可以添加到新文件中,也可以添加到窗体源代码的下方。

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继承而来的类。

1.public class SpellingOptionsConverter:ExpandableObjectConverter
2.{ }
2.如果destinationType 参数与使用此类型转换器的类(示例中的SpellingOptions
类)的类型相同,则覆盖CanConvertTo方法并返回true;否则返回基类CanConvertTo方法的值。

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中,因此需要选择一个不会影响可读性的分隔符,逗号的效果通常比较好。

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方法的值。

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方法中创建的分隔字符串的格式将有助于您的解析。

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);
ma = 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 类)来执行此操作。

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继承;这里并不需要。

1.public class FileNameConverter: StringConverter { }
2.覆盖GetStandardValuesSupported 方法并返回true,表示此对象支持可以从列表中选取的一
组标准值。

1.public override bool GetStandardValuesSupported(ITypeDescriptorContext
context)
2.{
3.return true;
4.}
3.覆盖GetStandardValues 方法并返回填充了标准值的StandardValuesCollection。

创建
StandardValuesCollection 的方法之一是在构造函数中提供一个值数组。

对于选项窗口应用程序,您可以使用填充了建议的默认文件名的String 数组。

1.public override StandardValuesCollection
GetStandardValues(ITypeDescriptorContext context)
2.{
3.return new StandardValuesCollection(new string[]{"新文件", "文件1", "文档1"});
4.}
4.(可选)如果希望用户能够键入下拉列表中没有包含的值,请覆盖GetStandardValuesExclusive
方法并返回false。

这从根本上将下拉列表样式变成了组合框样式。

1.public override bool GetStandardValuesExclusive(ITypeDescriptorContext
context)
2.{
3.return false;
4.}
5.拥有自己的用于显示下拉列表的类型转换器类后,您需要确定使用该类的目标。

在本示例中,目
标为DefaultFileName属性,因为类型转换器是针对该属性的。

将TypeConverterAttribute 应
用到目标属性中。

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)加入日期控件
编辑日期类型数据
ing System;
2.
ing System.Windows.Forms;
4.
ing System.Drawing.Design;
6.
ing System.Windows.Forms.Design;
8.
space .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(ponentModel.ITypeDescriptorContext context)
34.
35.{
36.
37.return UITypeEditorEditStyle.DropDown;
38.
39.}
40.
41.public override object EditValue(ponentModel.ITypeDescriptorContext context,
42.
43.System.IServiceProvider provider, object value)
44.
45.{
46.
47.try
49.{
50.
51.IWindowsFormsEditorService edSvc =
52.
53.(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
54.
55.if (edSvc != null)
56.
57.{
58.
59.if (value is string)
60.
61.{
62.
63.dateControl.SelectionStart = DateTime.Parse(value as String);
64.
65.edSvc.DropDownControl(dateControl);
66.
67.return dateControl.SelectionStart.ToShortDateString();
68.
69.}
70.
71.else if (value is DateTime)
72.
73.{
74.
75.dateControl.SelectionStart = (DateTime)value;
76.
77.edSvc.DropDownControl(dateControl);
78.
79.return dateControl.SelectionStart;
80.
81.}
82.
83.}
84.
85.}
86.
87.catch (Exception ex)
88.
89.{
90.
91.System.Console.WriteLine("PropertyGridDateItem Error : " + ex.Message);
93.return value;
94.
95.}
96.
97.return value;
98.
99.}
100.
101.}
102.
103.}
步骤二:编辑属性类,指定编辑属性。

示例如下:
space .zhangyuk
2.
3.{
4.
5.public class SomeProperties
6.
7.{
8.
9.private string _finished_time = "";
10.
11.//……
12.
13.[Description("完成时间"), Category("属性"),
EditorAttribute(typeof(PropertyGridDateItem),
14.
15.typeof(System.Drawing.Design.UITypeEditor))]
16.
17.public String 完成时间
18.
19.{
20.
21.get { return _finished_date; }
22.
23.set { _finished_date = value; }
24.
25.}
26.
27.//……
28.
29.}
31.}
步骤三:设置 PropertyGrid 的属性对象。

示例如下:
1.
2.private void Form1_Load(object sender, System.EventArgs e)
3.
4.{
5.
6.this.propertyGrid1.SelectedObject = new SomeProperties();
7.
8.}
改变 PropertyGrid 控件的编辑风格(2)——编辑多行文本
效果:
适用场合:
1、编辑多行文本;
2、编辑长文本。

步骤一:定义从UITypeEditor 派生的类,示例如下:
ing System;
2.
ing System.Windows.Forms;
4.
ing System.Drawing.Design;
6.
ing System.Windows.Forms.Design;
8.
space .zhangyuk
10.
11.{
12.
13./// <summary>
14.
15./// PropertyGridMutiText 的摘要说明。

16.
17./// </summary>
18.
19.public class PropertyGridRichText : UITypeEditor
20.
21.{
22.
23.public override UITypeEditorEditStyle
GetEditStyle(ponentModel.ITypeDescriptorContext context)
24.
25.{
26.
27.return UITypeEditorEditStyle.DropDown;
28.
29.}
30.
31.public override object EditValue(ponentModel.ITypeDescriptorContext context,
System.IServiceProvider provider, object value)
32.
33.{
34.
35.try
36.
37.{
38.
39.IWindowsFormsEditorService edSvc =
40.
41.(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
42.
43.if (edSvc != null)
44.
45.{
46.
47.if (value is string)
48.
49.{
50.
51.RichTextBox box = new RichTextBox();
52.
53.box.Text = value as string;
54.
55.edSvc.DropDownControl(box);
56.
57.return box.Text;
58.
59.}
60.
61.}
62.
63.}
64.
65.catch (Exception ex)
66.
67.{
68.
69.System.Console.WriteLine("PropertyGridRichText Error : " + ex.Message);
70.
71.return value;
72.
73.}
74.
75.return value;
76.
77.}
78.
79.}
80.
81.}
步骤二:编辑属性类,指定编辑属性。

示例如下:
1.
space .zhangyuk
3.
4.{
5.
6.public class SomeProperties
7.
8.{
9.
10.private string _finished_time = "";
11.
12.// ……
13.
14.// 多行文本编辑框
15.
16.string _mutiLineSample = "";
17.
18.[Description("多行文本编辑框"), Category("属性"),
EditorAttribute(typeof(PropertyGridRichText),
19.
20.typeof(System.Drawing.Design.UITypeEditor))]
21.
22.public String 多行文本
23.
24.{
25.
26.get { return _mutiLineSample; }
27.
28.set { _mutiLineSample = value; }
29.
30.}
31.
32.//……
33.
34.}
35.
36.}
步骤三:设置PropertyGrid的属性对象。

示例如下:
1.
2.private void Form1_Load(object sender, System.EventArgs e)
3.
4.{
5.
6.this.propertyGrid1.SelectedObject = new SomeProperties();
7.
8.}
改变 PropertyGrid 控件的编辑风格(3)——打开对话框
适用场合:
1、打开文件、打印设置等通用对话框
2、打开特定的对话框
步骤一:定义从UITypeEditor 派生的类,以 OpenFileDialog 对话框为例,示例代码如下:
1.
ing System;
3.
ing System.Windows.Forms;
5.
ing System.Drawing.Design;
7.
ing System.Windows.Forms.Design;
9.
space .zhangyuk
11.
12.{
13.
14./// <summary>
15.
16./// IMSOpenFileInPropertyGrid 的摘要说明。

17.
18./// </summary>
19.
20.public class PropertyGridFileItem : UITypeEditor
21.
22.{
23.
24.public override UITypeEditorEditStyle
GetEditStyle(ponentModel.ITypeDescriptorContext context)
25.
26.{
27.
28.return UITypeEditorEditStyle.Modal;
29.
30.}
31.
32.public override object EditValue(ponentModel.ITypeDescriptorContext context,
System.
33.
34.IServiceProvider provider, object value)
35.
36.{
37.
38.IWindowsFormsEditorService edSvc =
39.
40.(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
41.
42.if (edSvc != null)
43.
44.{
45.
46.// 可以打开任何特定的对话框
47.
48.OpenFileDialog dialog = new OpenFileDialog();
49.
50.dialog.AddExtension = false;
51.
52.if (dialog.ShowDialog().Equals(DialogResult.OK))
53.
54.{
55.
56.return dialog.FileName;
57.
59.
60.}
61.
62.return value;
63.
64.}
65.
66.}
67.
68.}
步骤二:编辑属性类,指定编辑属性。

示例如下:
1.
space .zhangyuk
3.
4.{
5.
6.public class SomeProperties
7.
8.{
9.
10.private string _finished_time = "";
11.
12.//……
13.
14.// 文件
15.
16.string _fileName = "";
17.
18.[Description("文件打开对话框"), Category("属性"),
EditorAttribute(typeof(PropertyGridFileItem),
19.
20.typeof(System.Drawing.Design.UITypeEditor))]
21.
22.public String 文件
23.
24.{
25.
26.get { return _fileName; }
27.
28.set { _fileName = value; }
29.
30.}
32.//……
33.
34.}
35.
36.}
步骤三:设置PropertyGrid的属性对象。

示例如下:
1.
2.private void Form1_Load(object sender, System.EventArgs e)
3.
4.{
5.
6.this.propertyGrid1.SelectedObject = new SomeProperties();
7.
8.}
改变 PropertyGrid 控件的编辑风格(4)——加入选择列表
适用场合:限制选择输入
步骤一:定义从UITypeEditor 继承的抽象类:ComboBoxItemTypeConvert。

示例如下:
1.
ing System;
3.
ing System.Collections;
5.
ing ponentModel;
7.
space .zhangyuk
9.
10.{
11.
12./// IMSTypeConvert 的摘要说明。

13.
14.public abstract class ComboBoxItemTypeConvert : TypeConverter
15.
16.{
17.
18.public Hashtable _hash = null;
19.
20.public ComboBoxItemTypeConvert()
21.
22.{
23.
24._hash = new Hashtable();
25.
26.GetConvertHash();
27.
28.}
29.
30.public abstract void GetConvertHash();
31.
32.public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
33.
34.{
35.
36.return true;
37.
38.}
39.
40.public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext
context)
41.
42.{
43.
44.int[] ids = new int[_hash.Values.Count];
45.
46.int i = 0;
47.
48.foreach (DictionaryEntry myDE in _hash)
49.
50.{
51.
52.ids[i++] = (int)(myDE.Key);
53.
54.}
55.
56.return new StandardValuesCollection(ids);
57.
58.}
59.
60.public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
61.
62.{
63.
64.if (sourceType == typeof(string))
65.
66.{
68.return true;
69.
70.}
71.
72.return base.CanConvertFrom(context, sourceType);
73.
74.}
75.
76.public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object v)
77.
78.{
79.
80.if (v is string)
81.
82.{
83.
84.foreach (DictionaryEntry myDE in _hash)
85.
86.{
87.
88.if (myDE.Value.Equals((v.ToString())))
89.
90.return myDE.Key;
91.
92.}
93.
94.}
95.
96.return base.ConvertFrom(context, culture, v);
97.
98.}
99.
100.public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
101.
102.object v, Type destinationType)
103.
104.{
105.
106.if (destinationType == typeof(string))
107.
108.{
110.foreach (DictionaryEntry myDE in _hash)
111.
112.{
113.
114.if (myDE.Key.Equals(v))
115.
116.return myDE.Value.ToString();
117.
118.}
119.
120.return "";
121.
122.}
123.
124.return base.ConvertTo(context, culture, v, destinationType);
125.
126.}
127.
128.public override bool GetStandardValuesExclusive(
129.
130.ITypeDescriptorContext context)
131.
132.{
133.
134.return false;
135.
136.}
137.
138.}
139.
140.}
步骤二:定义 ComboBoxItemTypeConvert 的派生类,派生类中实现父类的抽象方法:public abstract void GetConvertHash(); 示例如下:
1.
ing System;
3.
ing System.Collections;
5.
ing ponentModel;
7.
space .zhangyuk
9.
11.
12.public class PropertyGridBoolItem : ComboBoxItemTypeConvert
13.
14.{
15.
16.public override void GetConvertHash()
17.
18.{
19.
20._hash.Add(0, "是");
21.
22._hash.Add(1, "否");
23.
24.}
25.
26.}
27.
28.public class PropertyGridComboBoxItem : ComboBoxItemTypeConvert
29.
30.{
31.
32.public override void GetConvertHash()
33.
34.{
35.
36._hash.Add(0, "炒肝");
37.
38._hash.Add(1, "豆汁");
39.
40._hash.Add(2, "灌肠");
41.
42.}
43.
44.}
45.
46.}
步骤三:编辑属性类,指定编辑属性。

示例如下:
1.
space .zhangyuk
3.
4.{
5.。

相关文档
最新文档