当前位置:首页 > 网络编程 > WEB编程 > ASP.net >  深度解析 TypeConverter & TypeConverterAttribute (一

 深度解析 TypeConverter & TypeConverterAttribute (一

点击次数:15 次 发布日期:2008-11-26 10:33:33 作者:源代码网
源代码网推荐     
源代码网推荐  前言
源代码网推荐   我们在开发复杂控件的时候不可避免的碰到类型转换TypeConverter,微软给我们提供了很多转换类如ArrayConverter,BaseNumberConverter,BooleanConverter(MSDN上更多:ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.NETDEVFX.v20.en/cpref3/html/N_System_ComponentModel.htm)等直接或间接的继承了TypeConverter类。我们在类型转换的时候经常用到这些类。然而我们如何编写自定义的TypeConverter类呢,又怎么样在复杂控件中使用呢。
源代码网推荐  
源代码网推荐  TypeConverter Class
源代码网推荐   TypeConverter类就是将一种类型(object,可以说是任何类型)转换到另一种类型(一般为string),或者将另一种类型转换回来。所有继承TypeConverter类型的都必须实现4个方法:(这里以另一种类型string为例)
源代码网推荐   CanConverterTo 有两个重载方法,
源代码网推荐   TypeConverter.CanConvertTo (Type)
源代码网推荐   TypeConverter.CanConvertTo (ITypeDescriptorContext, Type)
源代码网推荐   都有一个Type参数(要转换成什么类型),例如我们设计的要转换成string,在方法体里面判断这个参数的Type如果是string,则返回true,否则返回 false
源代码网推荐   ConverterTo 也有两重载,
源代码网推荐   TypeConverter.ConvertTo (Object, Type)
源代码网推荐   TypeConverter.ConvertTo (ITypeDescriptorContext, CultureInfo, Object, Type)
源代码网推荐   都有Object和Type参数,将Object转成Type类型的Object,返回Type类型的Object。
源代码网推荐   下面类似的两个方法,不过方向相反,是从其他类型装换回来。
源代码网推荐   CanConverterFrom 重载,
源代码网推荐   TypeConverter.CanConvertFrom (Type)
源代码网推荐   TypeConverter.CanConvertFrom (ITypeDescriptorContext, Type)
源代码网推荐   在方法体里面判断参数Type是不是能转换回来的类型,例如string类型,如果是返回true,否则返回false。
源代码网推荐   ConverterFrom 重载,
源代码网推荐   TypeConverter.ConvertFrom (Object)
源代码网推荐   TypeConverter.ConvertFrom (ITypeDescriptorContext, CultureInfo, Object)
源代码网推荐   在方法体里面判断参数Object的类型是不是能转换回来的类型,例如string类型,如果是返回转换回来的类型。
源代码网推荐  
源代码网推荐   举例说明,以GPS经纬度位置为例,经纬度位置GPSLocation包括复杂属性经度Longitude和纬度Latitude。现我们根据其一属性Longitude类写个LongtitudeTypeConverter类。
源代码网推荐   首先我们得有个Longtitude类吧。
源代码网推荐  public class Longitude
源代码网推荐  {
源代码网推荐   private int _Degrees;
源代码网推荐   private int _Minutes;
源代码网推荐   private int _Seconds;
源代码网推荐   private LongitudeDirection _Direction;
源代码网推荐  
源代码网推荐   /// <summary>
源代码网推荐   /// 度数
源代码网推荐   /// </summary>
源代码网推荐   public int Degrees { }
源代码网推荐  
源代码网推荐   /// <summary>
源代码网推荐   /// 分度
源代码网推荐   /// </summary>
源代码网推荐   public int Minutes { }
源代码网推荐  
源代码网推荐   /// <summary>
源代码网推荐   /// 秒读
源代码网推荐   /// </summary>
源代码网推荐   public int Seconds { }
源代码网推荐  
源代码网推荐   /// <summary>
源代码网推荐   /// 方向
源代码网推荐   /// </summary>
源代码网推荐   public LongitudeDirection Direction
源代码网推荐   {
源代码网推荐   }
源代码网推荐  }有了个这个类,我们怎样将其转换到string类或其他类呢(这里假设string类)例如“24W3"4”形式,也许你会说重写ToString()方法不就行了,似乎可行,但如果转换成其他类呢,又从其他类转换回来呢,怎么办。还有在复杂控件中Designer设计中又该怎么办。(在复杂控件的应用稍后介绍)
源代码网推荐   自然,这样我们是不是要写个转换类比较好呢,这个类必须直接或这间接继承TypeConverter类。
源代码网推荐  
源代码网推荐   class LongitudeTypeConverter : TypeConverter
源代码网推荐   {
源代码网推荐  
源代码网推荐   }
源代码网推荐  
源代码网推荐  
源代码网推荐  然后重载实现上面说的四个方法,现在我要Longitude类转换到string类型
源代码网推荐  
源代码网推荐  CanConverterFrom
源代码网推荐  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
源代码网推荐   {
源代码网推荐   if (sourceType == typeof(string))
源代码网推荐   return true;
源代码网推荐   else
源代码网推荐   return base.CanConvertFrom(context, sourceType);
源代码网推荐   }
源代码网推荐  CanConverterTo
源代码网推荐  public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
源代码网推荐   {
源代码网推荐   if ((destinationType == typeof(string)) |
源代码网推荐   (destinationType == typeof(InstanceDescriptor)))
源代码网推荐   return true;
源代码网推荐   else
源代码网推荐   return base.CanConvertTo(context, destinationType);
源代码网推荐   }
源代码网推荐  ConvertTo
源代码网推荐  public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
源代码网推荐   {
源代码网推荐   // check that the value we got passed on is of type Longitude
源代码网推荐   if (value != null)
源代码网推荐   if (!(value is Longitude))
源代码网推荐   throw new Exception(WrongType);
源代码网推荐  
源代码网推荐   // convert to a string
源代码网推荐   if (destinationType == typeof(string))
源代码网推荐   {
源代码网推荐   // no value so we return an empty string
源代码网推荐   if (value == null)
源代码网推荐   return string.Empty;
源代码网推荐  
源代码网推荐   // strongly typed
源代码网推荐   Longitude LongValue = value as Longitude;
源代码网推荐  
源代码网推荐   // get the two type converters to use
源代码网推荐   TypeConverter IntConverter = TypeDescriptor.GetConverter(typeof(int));
源代码网推荐   TypeConverter EnumConverter = TypeDescriptor.GetConverter(typeof(LongitudeDirection));
源代码网推荐  
源代码网推荐   // convert to a string and return
源代码网推荐   return IntConverter.ConvertToString(context, culture, LongValue.Degrees) +
源代码网推荐   EnumConverter.ConvertToString(context, culture, LongValue.Direction).Substring(0, 1) +
源代码网推荐   IntConverter.ConvertToString(context, culture, LongValue.Minutes) + MinutesUnit +
源代码网推荐   IntConverter.ConvertToString(context, culture, LongValue.Seconds) + SecondsUnit;
源代码网推荐   }
源代码网推荐  
源代码网推荐   // convert to a instance descriptor
源代码网推荐   if (destinationType == typeof(InstanceDescriptor))
源代码网推荐   {
源代码网推荐   // no value so we return no instance descriptor
源代码网推荐   if (value == null)
源代码网推荐   return null;
源代码网推荐  
源代码网推荐   // strongly typed
源代码网推荐   Longitude LongValue = value as Longitude;
源代码网推荐  
源代码网推荐   // used to descripe the constructor
源代码网推荐   MemberInfo Member = null;
源代码网推荐   object[] Arguments = null;
源代码网推荐  
源代码网推荐   // get the constructor for the type
源代码网推荐   Member = typeof(Longitude).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(LongitudeDirection) });
源代码网推荐  
源代码网推荐   // create the arguments to pass along
源代码网推荐   Arguments = new object[] { LongValue.Degrees, LongValue.Minutes, LongValue.Seconds, LongValue.Direction };
源代码网推荐  
源代码网推荐   // return the instance descriptor
源代码网推荐   if (Member != null)
源代码网推荐   return new InstanceDescriptor(Member, Arguments);
源代码网推荐   else
源代码网推荐   return null;
源代码网推荐   }
源代码网推荐  
源代码网推荐   // call the base converter
源代码网推荐   return base.ConvertTo(context, culture, value, destinationType);
源代码网推荐   }
源代码网推荐  ConvertFrom
源代码网推荐  public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
源代码网推荐   {
源代码网推荐   // no value so we return a new Longitude instance
源代码网推荐   if (value == null)
源代码网推荐   return new Longitude();
源代码网推荐  
源代码网推荐   // convert from a string
源代码网推荐   if (value is string)
源代码网推荐   {
源代码网推荐   // get strongly typed value
源代码网推荐   string StringValue = value as string;
源代码网推荐  
源代码网推荐   // empty string so we return a new Longitude instance
源代码网推荐   if (StringValue.Length <= 0)
源代码网推荐   return new Longitude();
源代码网推荐  
源代码网推荐   // get the position of the West longitude separator
源代码网推荐   int DirectionPos = StringValue.IndexOf(LongitudeDirection.West.ToString().Substring(0, 1));
源代码网推荐   LongitudeDirection Direction = LongitudeDirection.West;
源代码网推荐  
源代码网推荐   // if not found get the position of the East longitude separator
源代码网推荐   if (DirectionPos == -1)
源代码网推荐   {
源代码网推荐   DirectionPos = StringValue.IndexOf(LongitudeDirection.East.ToString().Substring(0, 1));
源代码网推荐   Direction = LongitudeDirection.East;
源代码网推荐   }
源代码网推荐  
源代码网推荐   // get the minutes and seconds characters
源代码网推荐   int MinutesPos = StringValue.IndexOf(MinutesUnit);
源代码网推荐   int SecondsPos = StringValue.IndexOf(SecondsUnit);
源代码网推荐  
源代码网推荐   // no minutes present
源代码网推荐   if (MinutesPos == -1)
源代码网推荐   throw new Exception(MinutesMissing);
源代码网推荐  
源代码网推荐   // no seconds present
源代码网推荐   if (SecondsPos == -1)
源代码网推荐   throw new Exception(SecondsMissing);
源代码网推荐  
源代码网推荐   // no minutes present
源代码网推荐   if (DirectionPos == -1)
源代码网推荐   throw new Exception(DirectionMissing);
源代码网推荐  
源代码网推荐   // no degrees present
源代码网推荐   if (DirectionPos == 0)
源代码网推荐   throw new Exception(DegreesMissing);
源代码网推荐  
源代码网推荐   // get the type converters we need
源代码网推荐   TypeConverter IntConverter = TypeDescriptor.GetConverter(typeof(int));
源代码网推荐  
源代码网推荐   // get the degrees, minutes and seconds value
源代码网推荐   int Degrees = (int)IntConverter.ConvertFromString(context, culture, StringValue.Substring(0, DirectionPos));
源代码网推荐   int Minutes = (int)IntConverter.ConvertFromString(context, culture, StringValue.Substring(DirectionPos + 1, MinutesPos - DirectionPos - 1));
源代码网推荐   int Seconds = (int)IntConverter.ConvertFromString(context, culture, StringValue.Substring(MinutesPos + 1, SecondsPos - MinutesPos - 1));
源代码网推荐  
源代码网推荐   // create a new Longitude instance with these values and return it
源代码网推荐   return new Longitude(Degrees, Minutes, Seconds, Direction);
源代码网推荐   }
源代码网推荐  
源代码网推荐   // otherwise call the base converter
源代码网推荐   else
源代码网推荐   return base.ConvertFrom(context, culture, value);
源代码网推荐   }
源代码网推荐  有了这个转换类LongitudeTypeConverter,该怎么使用呢。其实很简单就是使用我们上面实现的四个方法,
源代码网推荐   class Test
源代码网推荐   {
源代码网推荐   public static void Main(string[] args)
源代码网推荐   {
源代码网推荐   //将Longitude类转换到string类型
源代码网推荐   Longitude longitude = new Longitude(10,11,12,LongitudeDirection.East);
源代码网推荐   LongitudeTypeConverter converter = new LongitudeTypeConverter();
源代码网推荐  
源代码网推荐   string strLongitude="";
源代码网推荐   if (converter.CanConvertTo(typeof(string)))
源代码网推荐   {
源代码网推荐   strLongitude = (string)converter.ConvertTo(longitude, typeof(string));
源代码网推荐   }
源代码网推荐   System.Console.WriteLine(strLongitude);
源代码网推荐  
源代码网推荐   //将string还原回Longitude类
源代码网推荐   Longitude longitude1 = new Longitude();
源代码网推荐   if (converter.CanConvertFrom(typeof(string)))
源代码网推荐   {
源代码网推荐   longitude1 = (Longitude)converter.ConvertFrom(strLongitude);
源代码网推荐   }
源代码网推荐   System.Console.WriteLine(longitude1.Degrees);
源代码网推荐   System.Console.WriteLine(longitude1.Direction);
源代码网推荐   System.Console.WriteLine(longitude1.Minutes);
源代码网推荐   System.Console.WriteLine(longitude1.Seconds);
源代码网推荐   }
源代码网推荐   }输出结果是
源代码网推荐  10E11"12""
源代码网推荐  10
源代码网推荐  East
源代码网推荐  11
源代码网推荐  12
源代码网推荐  从结果中我们可以看到实现了我们预期的效果。
源代码网推荐  这些在一般代码里面可以用到,但从转换的结果中我们可以联想,web页面设计的两种模式(设计模式,源代码模式),在源代码模式我们显示的是string,但在设计模式我们显示控件的外观,这里就关系到TypeConverter类了,当然还有TypeConverterAtrribute。
源代码网推荐  下面就要说下这个TypeConverterAtrribute了。  做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。
源代码网推荐


源代码网供稿.
网友评论 (0)
会员中心
网络编程
本站推荐
网络编程之精华