.net WinForm用户控件开发--(5)用户控件复杂属性设置
这一节,大家共同学习下,用户控件的自定义的复杂的属性设置,我们这里自定义一个用户控件和自定义一个属性。
本节重点:
1.怎样定义复杂属性
2.复杂属性和基本类型相互转换
1.第一步, 先来自定义一个类,代码如下
[csharp]
/// <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;
}
}
}
/// <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,代码如下
[csharp]
public partial class ucpanel : control
{
public ucpanel()
{
initializecomponent();
}
private customattri _ssize=new customattri(20,30);;
/// <summary>
/// 定义自定义属性
/// </summary>
[description("第二尺寸")]
[category("尺寸")]
public customattri secondsize
{
get
{
return _ssize;
}
set
{
_ssize=value;
}
}
}
public partial class ucpanel : control
{
public ucpanel()
{
initializecomponent();
}
private customattri _ssize=new customattri(20,30);;
/// <summary>
/// 定义自定义属性
/// </summary>
[description("第二尺寸")]
[category("尺寸")]
public customattri secondsize
{
get
{
return _ssize;
}
set
{
_ssize=value;
}
}
}
此时编译项目,然后把用户控件拖到窗体上,就可以在属性设计器中看到此属性,但是此时属性是只读的,不能设置值。
效果图如下:
2. 接下来,我们实现让用户可以自己设置属性的值,并把用户输入的值进行转换。
如果想要把用户输入的值转换为我们自定义的类型,需要继承typeconverter 类,并实现其方法。
转换器代码如下:
[csharp]
/// <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 base.canconvertfrom(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 base.canconvertto(context, destinationtype);
}
/// <summary>
/// 将指定类型转换为自定义类型
/// </summary>
/// <param name="context">当前上下文信息</param>
/// <param name="culture">区域信息</param>
/// <param name="value">指定类型</param>
/// <returns></returns>
public override object convertfrom(itypedescriptorcontext context, system.globalization.cultureinfo culture, object value)
{
if (value is string)
{
string[] sizearr = ((string)value).split(',');//将输入的字符串以逗号进行分割
customattri ca = new customattri();
ca.width=convert.toint16(sizearr[0]);
ca.height=convert.toint16(sizearr[1]);
return ca;
}
return base.convertfrom(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, system.globalization.cultureinfo culture, object value, type destinationtype)
{
//如果要转换为自定义类型
if (destinationtype==typeof(string))
{
if (value is customattri)
{
customattri ca = (customattri)value;
return ca.width.tostring() + "," + ca.height.tostring();
}
}
return base.convertto(context, culture, value, destinationtype);
}
}
/// <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 base.canconvertfrom(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 base.canconvertto(context, destinationtype);
}
/// <summary>
/// 将指定类型转换为自定义类型
/// </summary>
/// <param name="context">当前上下文信息</param>
/// <param name="culture">区域信息</param>
/// <param name="value">指定类型</param>
/// <returns></returns>
public override object convertfrom(itypedescriptorcontext context, system.globalization.cultureinfo culture, object value)
{
if (value is string)
{
string[] sizearr = ((string)value).split(',');//将输入的字符串以逗号进行分割
customattri ca = new customattri();
ca.width=convert.toint16(sizearr[0]);
ca.height=convert.toint16(sizearr[1]);
return ca;
}
return base.convertfrom(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, system.globalization.cultureinfo culture, object value, type destinationtype)
{
//如果要转换为自定义类型
if (destinationtype==typeof(string))
{
if (value is customattri)
{
customattri ca = (customattri)value;
return ca.width.tostring() + "," + ca.height.tostring();
}
}
return base.convertto(context, culture, value, destinationtype);
}
}
然后把该转换器标记在自定义属性上,这样在窗体上,就可以为该用户控件的属性设置值了
[csharp]
[description("第二尺寸")]
[category("尺寸")]
[typeconverter(typeof(customattriconverter))]
public customattri secondsize
{
get
{
return _ssize;
}
set
{
_ssize=value;
}
}
[description("第二尺寸")]
[category("尺寸")]
[typeconverter(typeof(customattriconverter))]
public customattri secondsize
{
get
{
return _ssize;
}
set
{
_ssize=value;
}
}
效果图:
3.子属性的实现
上面代码虽然实现了可以给自定义属性设置值,但是字属性不能显示出来,如果想实现把子属性显示出来,需要重载以下方法
[csharp]
/// <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 base.getproperties(context, value, attributes);
return typedescriptor.getproperties(typeof(customattri), attributes);
}
/// <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 base.getproperties(context, value, attributes);
return typedescriptor.getproperties(typeof(customattri), attributes);
}
效果图:
至此,复杂自定义属性的设置,我们已经讲解完成。
作者:zx13525079024
推荐阅读
-
.net WinForm用户控件开发--(5)用户控件复杂属性设置
-
.net WinForm用户控件开发--(1)带按钮的textbox控件
-
.net WinForm用户控件开发--(3)可多选的下拉列表框
-
.net WinForm用户控件开发--(2)带按钮DataGridView
-
.net WinForm用户控件开发--(5)用户控件复杂属性设置
-
.net WinForm用户控件开发--(7)用户控件下拉式属性设置
-
.net WinForm用户控件开发--(1)带按钮的textbox控件
-
.net WinForm用户控件开发--(3)可多选的下拉列表框
-
.net WinForm用户控件开发--(2)带按钮DataGridView