上一篇文章是03-08寫的,距離今天已經有十多天了沒有寫了,主要是最近太忙了,而且在工作上遇到 了一些難點,所以沒有時間放在blog上,實在是對不住大家。
今天的這篇文章,我主要是帶來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; }
}
}
}
下一篇文章將為大家帶來Component Designer的講解。
隨文源碼:http://www.bianceng.net/dotnet/201212/663.htm