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"; } }