添加域列表和简单的下拉列表属性支持 对于基于 Enum 类型返回枚举的属性,PropertyGrid 会自动在下拉列表中显示枚举值。EnumConverter 也提供了这一功能。对于自己的属性,您可能希望为用户提供一个有效值列表(有时也称为选取列表或域列表),而其类型并不是基于 Enum。如果域值在运行时之前未知,或者值可以更改,则属于这种情况。
修改选项窗口,提供一个用户可从中选择的默认文件名的域列表。您已经将 DefaultFileName 属性添加到 AppSettings 类。下一步是在 PropertyGrid 中显示属性的下拉列表,以提供域列表。
提供简单的下拉列表属性支持 创建一个从类型转换器类继承而来的类。由于 DefaultFileName 属性属于 String 类型,因此可以从 StringConverter 中继承。如果属性类型的类型转换器不存在,则可以从 TypeConverter 继承;这里并不需要。 ' Visual Basic
Public Class FileNameConverter Inherits StringConverter End Class 覆盖 GetStandardValuesSupported 方法并返回 true,表示此对象支持可以从列表中选取的一组标准值。 ' Visual Basic
Public Overloads Overrides Function GetStandardValuesSupported( _ ByVal context As ITypeDescriptorContext) As Boolean Return True End Function
覆盖 GetStandardValues 方法并返回填充了标准值的 StandardValuesCollection。创建 StandardValuesCollection 的方法之一是在构造函数中提供一个值数组。对于选项窗口应用程序,您可以使用填充了建议的默认文件名的 String 数组。 ' Visual Basic
Public Overloads Overrides Function GetStandardValues( _ ByVal context As ITypeDescriptorContext) _ As StandardValuesCollection
Return New StandardValuesCollection(New String() {"新文件", _ "文件1", _ "文档1"}) End Function (可选)如果希望用户能够键入下拉列表中没有包含的值,请覆盖 GetStandardValuesExclusive 方法并返回 false。这从根本上将下拉列表样式变成了组合框样式。 ' Visual Basic
Public Overloads Overrides Function GetStandardValuesExclusive( _ ByVal context As ITypeDescriptorContext) As Boolean Return False End Function
拥有自己的用于显示下拉列表的类型转换器类后,您需要确定使用该类的目标。在本示例中,目标为 DefaultFileName 属性,因为类型转换器是针对该属性的。将 TypeConverterAttribute 应用到目标属性中。 ' Visual Basic
' 应用到 DefaultFileName 属性的 TypeConverter 特性。 <TypeConverter(GetType(FileNameConverter)), _ CategoryAttribute("文档设置")> _ Public Property DefaultFileName() As String Get Return _defaultFileName End Get Set(ByVal Value As String) _defaultFileName = Value End Set End Property
再次编译并运行选项窗口应用程序。下面的屏幕快照显示了选项窗口目前的外观。请注意 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 中显示自定义选项卡
有关使用 UITypeEditor 类自定义 PropertyGrid 的详细信息,以及上述自定义用户界面代码示例,请参阅 Shawn Burke 的文章 Make Your Components Really RAD with Visual Studio .NET Property Browser(英文)。
小结 .NET 框架提供的 ProperyGrid 控件具有丰富的编辑功能,您可以使用这些编辑功能来改善您的用户界面。PropertyGrid 的自定义非常简单,您可以在任何应用程序中使用这一控件。此外,由于 Visual Studio .NET 属性浏览器是建立在 PropertyGrid 的基础之上的,因此您可以使用这些技术提供更丰富的设计时体验。
|