这一节大家共同学习下用户控件的自定义的复杂的属性设置我们这里自定义一个用户控件和自定义一个属性
本节重点:
怎样定义复杂属性
复杂属性和基本类型相互转换
第一步先来自定义一个类代码如下
/// <summary> /// 自定义属性类 /// </summary> public class CustomAttri { public CustomAttri(int width int height) { _width = width; _height = height; } public CustomAttri() { } private int _width; private int _height; /// <summary> /// 宽度 /// </summary> public int Width { get { return _width; } set { _width = value; } } /// <summary> /// 高度 /// </summary> public int Height { get { return _height; } set { _height = value; } } }
然后自定义一个控件并且定义一属性SecondSize代码如下
public partial class UCPanel : Control { public UCPanel() { InitializeComponent(); } private CustomAttri _sSize=new CustomAttri();; /// <summary> /// 定义自定义属性 /// </summary> [Description(第二尺寸)] [Category(尺寸)] public CustomAttri SecondSize { get { return _sSize; } set { _sSize=value; } } }
此时编译项目然后把用户控件拖到窗体上就可以在属性设计器中看到此属性但是此时属性是只读的不能设置值
效果图如下
接下来我们实现让用户可以自己设置属性的值并把用户输入的值进行转换
如果想要把用户输入的值转换为我们自定义的类型需要继承TypeConverter 类并实现其方法
转换器代码如下:
/// <summary> /// 自定义类型转换器 /// </summary> public class CustomAttriConverter:TypeConverter { /// <summary> /// 表示是否允许将给定类型的对象转换为自定义类型 /// </summary> /// <param name=context>当前上下文对象</param> /// <param name=sourceType>给定的类型</param> /// <returns></returns> public override bool CanConvertFrom(ITypeDescriptorContext context Type sourceType) { //如果给定的类型为字符串可以转换为自定义类型 if (sourceType==typeof(string)) { return true; } return baseCanConvertFrom(context sourceType); } /// <summary> /// 表示是否允许将自定义类型转换为指定的类型 /// </summary> /// <param name=context>当前上下文</param> /// <param name=destinationType>指定的类型</param> /// <returns></returns> public override bool CanConvertTo(ITypeDescriptorContext context Type destinationType) { //如果目标类型是字符串允许将自定义类型转换为字符串 if (destinationType==typeof(string)) { return true; } return baseCanConvertTo(context destinationType); } /// <summary> /// 将指定类型转换为自定义类型 /// </summary> /// <param name=context>当前上下文信息</param> /// <param name=culture>区域信息</param> /// <param name=value>指定类型</param> /// <returns></returns> public override object ConvertFrom(ITypeDescriptorContext context SystemGlobalizationCultureInfo culture object value) { if (value is string) { string[] sizeArr = ((string)value)Split();//将输入的字符串以逗号进行分割 CustomAttri ca = new CustomAttri(); caWidth=ConvertToInt(sizeArr[]); caHeight=ConvertToInt(sizeArr[]); return ca; } return baseConvertFrom(context culture value); } /// <summary> /// 将自定义类型转换为指定类型 /// </summary> /// <param name=context>当前上下文</param> /// <param name=culture>区域</param> /// <param name=value></param> /// <param name=destinationType>指定类型</param> /// <returns></returns> public override object ConvertTo(ITypeDescriptorContext context SystemGlobalizationCultureInfo culture object value Type destinationType) { //如果要转换为自定义类型 if (destinationType==typeof(string)) { if (value is CustomAttri) { CustomAttri ca = (CustomAttri)value; return caWidthToString() + + caHeightToString(); } } return baseConvertTo(context culture value destinationType); } }
然后把该转换器标记在自定义属性上这样在窗体上就可以为该用户控件的属性设置值了
[Description(第二尺寸)] [Category(尺寸)] [TypeConverter(typeof(CustomAttriConverter))] public CustomAttri SecondSize { get { return _sSize; } set { _sSize=value; } }
效果图:
子属性的实现
上面代码虽然实现了可以给自定义属性设置值但是字属性不能显示出来如果想实现把子属性显示出来需要重载以下方法
/// <summary> /// 返回此对象是否支持属性 /// </summary> /// <param name=context></param> /// <returns></returns> public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; } public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context object value Attribute[] attributes) { //return baseGetProperties(context value attributes); return TypeDescriptorGetProperties(typeof(CustomAttri) attributes); }
效果图
至此复杂自定义属性的设置我们已经讲解完成