在上一篇ViewState——自定義狀態管理(一)中我在自定義屬性的類裡面加入了一個重寫的ToString方法和一個從字符串獲取一個該類型實例的一個構造函數。大家可能會覺得談到自定義屬性的狀態管理卻不提及TypeConverter(Attribute),有些神奇。好吧,下面就來說說TypeConverter。
先看下MSDN的解釋:提供一種將值的類型轉換為其他類型以及訪問標准值和子屬性的統一方法。
在上一篇我自己寫了兩個方法而沒有使用TypeConverter就是想從一方面說明TypeConverter的作用(從這一點來說就是類型轉換)。當然TypeConverter還有很多其他用途,比方說提供一組標准值什麼的。因此在通常情況下我們都使用TypeConverter來完成這些工作(即使僅僅是只處理類型轉換的問題)。就個人理解,TypeConverter是我們在屬性窗體為控件屬性輸入值以及在aspx或ascx聲明控件給控件屬性賦值時使用的,它可以控制怎樣將我們的輸入轉換成控件屬性對應的類型。您可能會說,其實我們自己也可以調用它來做些操作啊,對,這樣也可以。
首先,修改下以前的例子:
ViewStateManagement4
namespace Controls { using System; using System.Collections.Generic; using System.Text; using System.Web.UI; using System.ComponentModel; using System.Globalization; public class ViewStateManagement4 : Control { private CustomProperty4 m_Property; [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )] public CustomProperty4 Property { get { if (m_Property == null) { m_Property = new CustomProperty4(); } return m_Property; } //set //{ //} } protected override void LoadViewState(object savedState) { if (savedState is Pair) { Pair properties = (Pair)savedState; base.LoadViewState(properties.First); m_Property = (CustomProperty4)properties.Second; } else { base.LoadViewState(savedState); } } protected override object SaveViewState() { object baseState = base.SaveViewState(); if (Property != null) { return new Pair( baseState, Property); } return baseState; } protected override void TrackViewState() { base.TrackViewState(); } protected override void Render(HtmlTextWriter writer) { //CustomTypeConverter c = new CustomTypeConverter(); //c.ConvertTo(null, CultureInfo.InvariantCulture, Property, typeof(string)); //writer.Write(c.ConvertTo(null, CultureInfo.InvariantCulture, Property, typeof(string))); writer.Write(TypeDescriptor.GetConverter(Property.GetType()).ConvertTo(null, CultureInfo.InvariantCulture, Property, typeof(string))); } } [TypeConverter(typeof( CustomTypeConverter))] public class CustomProperty4 { private string m_Property1; private string m_Property2; public string Property2 { get { return m_Property2; } set { m_Property2 = value; } } public string Property1 { get { return m_Property1; } set { m_Property1 = value; } } } public class CustomTypeConverter : ExpandableObjectConverter { /**//// <summary> /// 指定是否可以從特定的類型進行轉換 /// </summary> /// <param name="context"></param> /// <param name="sourceType"></param> /// <returns>true:可以;false:不可以</returns> public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { //如果源類型是字符串 if (sourceType == typeof(string)) { return true; } return false; } /**//// <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 false; } /**//// <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 str = (string)value; string[] propertyValues = str.Split(';'); if (propertyValues.Length == 2) { CustomProperty4 obj = new CustomProperty4(); obj.Property1 = propertyValues[0]; obj.Property2 = propertyValues[1]; return obj; } } 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 (value is CustomProperty4) { CustomProperty4 obj = (CustomProperty4)value; return obj.Property1 + ";" + obj.Property2; } return base.ConvertTo(context, culture, value, destinationType); } } }