WinForms设计器属性的不同派生类型
假设我有一个特定的类型,我想让Windows窗体设计师使用…
public class Style { public CustomBrush Brush { get; set; } }
而CustomBrush
就像这样实现……
public abstract CustomBrush { ... } public SolidCustomBrush : CustomBrush { ... } public GradientCustomBrush : CustomBrush { ... }
在设计时有没有办法可以从CustomBrush
派生的任何类型中选择,实例化所选类型的实例,并通过设计器进行修改?
到目前为止,我能够做到这一点的唯一方法是使用enum
enum BrushType { Solid, Gradient }
当enum
改变时, Brush
属性的底层类型也会改变,但我不喜欢这种方法……它很脏!
作为选项,您可以创建自定义TypeConverter
,它提供要在PropertyGrid
显示的标准值列表。
类型转换器可以在“属性”窗口控件中提供类型的值列表。 当类型转换器为类型提供一组标准值时,“属性”窗口控件中相关类型的属性的值输入字段将显示一个向下箭头,该箭头显示一个值列表,用于设置单击时属性的值。
由于您希望能够在属性网格中编辑CustomBrush
子属性,因此您应该从ExpandableObjectConverter
派生。
结果
履行
创建CustomBrushConverter
类并从ExpandableObjectConverter
派生。 然后覆盖这些方法:
-
GetStandardValuesSupported
:返回true
以显示下拉列表。 -
GetStandardValuesExclusive
:返回true
以将支持的值限制为下拉列表。 -
GetStandardValues
:返回要在下拉列表中显示的可用选项列表。 所有值都应与您正在编辑的属性的类型相同(此处为CustomBrush
类型)。 -
CanConvertFrom
:如果sourceType
参数的类型为string
则返回true
。 -
ConvertFrom
:根据字符串value
参数返回标准值之一。
using System; using System.ComponentModel; using System.Linq; class CustomBrushConverter : ExpandableObjectConverter { CustomBrush[] standardValues = new CustomBrush[] { new SolidCustomBrush(), new GradientCustomBrush() }; public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) return true; return base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { var result = standardValues.Where(x => x.ToString() == value).FirstOrDefault(); if (result != null) return result; return base.ConvertFrom(context, culture, value); } public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return new StandardValuesCollection(standardValues); } }
然后使用TypeConverterAttribute
这种方式装饰Brush
属性:
public class Style /*: Component */ { [TypeConverter(typeof(CustomBrushConverter))] public CustomBrush Brush { get; set; } }
您可以覆盖CustomBrush
类的ToString
方法,以提供更友好的名称,以显示在PropertyGrid
下拉列表中。 例如:
public class GradientCustomBrush : CustomBrush { public Color Color1 { get; set; } public Color Color2 { get; set; } public override string ToString() { return "Gradient"; } }