不同派生类型的 WinForms 设计器属性
WinForms designer properties of different derived types
假设我有一个特定类型,我想提供给 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
中显示的标准值列表。
A type converter can provide a list of values for a type in a
Properties window control. When a type converter provides a set of
standard values for a type, the value entry field for a property of
the associated type in a Properties window control displays a down
arrow that displays a list of values to set the value of the property
to when clicked.
由于您还希望能够编辑 属性 网格中 CustomBrush
的子属性,因此您应该从 ExpandableObjectConverter
派生。
结果
实施
创建一个 CustomBrushConverter
class 并派生自 ExpandableObjectConverter
。然后覆盖这些方法:
GetStandardValuesSupported
: return true
显示下拉菜单。
GetStandardValuesExclusive
: return true
将支持的值限制为下拉列表。
GetStandardValues
:return 下拉列表中显示的可用选项列表。所有值都应与您正在编辑的 属性 类型相同(此处为 CustomBrush
类型)。
CanConvertFrom
: return true
如果 sourceType
参数的类型是 string
.
ConvertFrom
: return 基于字符串 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
class 的 ToString
方法,以提供更友好的名称以显示在 PropertyGrid
的下拉列表中。例如:
public class GradientCustomBrush : CustomBrush
{
public Color Color1 { get; set; }
public Color Color2 { get; set; }
public override string ToString()
{
return "Gradient";
}
}
假设我有一个特定类型,我想提供给 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
中显示的标准值列表。
A type converter can provide a list of values for a type in a Properties window control. When a type converter provides a set of standard values for a type, the value entry field for a property of the associated type in a Properties window control displays a down arrow that displays a list of values to set the value of the property to when clicked.
由于您还希望能够编辑 属性 网格中 CustomBrush
的子属性,因此您应该从 ExpandableObjectConverter
派生。
结果
实施
创建一个 CustomBrushConverter
class 并派生自 ExpandableObjectConverter
。然后覆盖这些方法:
GetStandardValuesSupported
: returntrue
显示下拉菜单。GetStandardValuesExclusive
: returntrue
将支持的值限制为下拉列表。GetStandardValues
:return 下拉列表中显示的可用选项列表。所有值都应与您正在编辑的 属性 类型相同(此处为CustomBrush
类型)。CanConvertFrom
: returntrue
如果sourceType
参数的类型是string
.ConvertFrom
: return 基于字符串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
class 的 ToString
方法,以提供更友好的名称以显示在 PropertyGrid
的下拉列表中。例如:
public class GradientCustomBrush : CustomBrush
{
public Color Color1 { get; set; }
public Color Color2 { get; set; }
public override string ToString()
{
return "Gradient";
}
}