今天的这篇文章,我主要是带来propertyattribute里的typeconverterattribute的讲解,首先在这里讲讲typeconverterattribute的作用是什么:当component的某个property被设置时,如size="60,70",解析器会通过类型转化器,把这个字符串自动转换为属性声明的类型。.net的框架中已经声明了很多的类型转化器,下面的代码中有列举到。有点类似于operator。
同时在asp.net服务器控件的编写中typeconverterattribute也将会非常有用,服务器控件的property只能以string形式保存在aspx页面里,而在服务器控件的designtime和runtime时必须要把string转换为相应的类型。
源代码如下:
using system;
using system.collections.generic;
using system.text;
using system.componentmodel;
using system.globalization;
namespace classlibrary1
{
public class class1 : component
{
private size _size;
public class1()
{
_size = new size();
}
[designerserializationvisibility(designerserializationvisibility.content)]
[typeconverter(typeof(sizeconverter))] // —— 注1,也可以把这句typeconverterattribute写在注2处。
public size size
{
get { return _size; }
set { _size = value; }
}
}
public class sizeconverter : typeconverter // 我们自定义的converter必须继承于typeconverter基类。
{
/**//// <summary>
/// 是否能用string转换到size类型。
/// </summary>
/// <param name="context">上下文。</param>
/// <param name="sourcetype">转换源的type。</param>
/// <returns></returns>
public override bool canconvertfrom(itypedescriptorcontext context, type sourcetype)
{
if (sourcetype == typeof(string))
{ return true; }
else
{ return false; }
}
/**//// <summary>
/// 从string转到size类型。
/// </summary>
/// <param name="context">提供component的上下文,如component.instance对象等。</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 == null || value.tostring().length == 0) return new size();
char spliter = culture.textinfo.listseparator[0]; // 得到字符串的分隔符
string[] ss = ((string)value).split(spliter);
int32converter intconverter = new int32converter(); // 得到类型转换器,.net中为我们定义了一些常见的类型转换器。
return new size((int32)intconverter.convertfromstring(context, culture, ss[0]),
(int32)intconverter.convertfromstring(context, culture, ss[1]));
}
/**//// <summary>
/// 是否能用size转换到string类型。
/// </summary>
/// <param name="context"></param>
/// <param name="destinationtype">转换目标的类型。</param>
/// <returns></returns>
public override bool canconvertto(itypedescriptorcontext context, type destinationtype)
{
if (destinationtype == typeof(size)) // 如果是size格式,则允许转成string。
{ return true; }
else
{ return false; }
}
// 在property窗口中显示为string类型。
public override object convertto(itypedescriptorcontext context, system.globalization.cultureinfo culture, object value, type destinationtype)
{
if (value == null) return string.empty;
if (destinationtype == typeof(string))
{
size size = (size)value;
typeconverter intconverter = typedescriptor.getconverter(typeof(int32)); // 能到类型转换器的另一种方式。
char spliter = culture.textinfo.listseparator[0]; // 得到字符串的分隔符
return string.join(spliter.tostring(), new string[]{
intconverter.converttostring(context, culture, size.length),
intconverter.converttostring(context, culture, size.width)});
}
return string.empty;
}
// typeconverter还有几个虚方法,请大家自己研究。
}
// [typeconverter(typeof(sizeconverter))] —— 注2
public class size
{
private int32 _length;
private int32 _width;
public size(int32 length, int32 width)
{
_length = length;
_width = width;
}
public size() : this(0, 0)
{}
public int32 length
{
get { return _length; }
set { _length = value; }
}
public int32 width
{
get { return _width; }
set { _width = value; }
}
}
}