上一篇介紹了自定義屬性類別中重寫 ToString 與建構函數來實現狀態管理,但為何不直接使用 TypeConverter?本文將詳細闡述 TypeConverter 的作用、核心方法與實際應用,並提供完整代碼範例。
根據 MSDN 定義:提供一種將值的類型轉換為其他類型、訪問標準值及子屬性的統一方法。在屬性視窗或 ASPX/ASCX 標記中為控件屬性賦值時,TypeConverter 負責將字串輸入轉換為目標類型實例。
繼承 ExpandableObjectConverter 並重寫以下四個關鍵方法:
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;
}
}
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) {
writer.Write(TypeDescriptor.GetConverter(Property.GetType())
.ConvertTo(null, CultureInfo.InvariantCulture, Property, typeof(string)));
}
}
[TypeConverter(typeof(CustomTypeConverter))]
public class CustomProperty4 {
private string m_Property1, m_Property2;
public string Property1 { get { return m_Property1; } set { m_Property1 = value; } }
public string Property2 { get { return m_Property2; } set { m_Property2 = value; } }
}
public class CustomTypeConverter : ExpandableObjectConverter {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
if (value is string) {
string[] parts = ((string)value).Split(';');
if (parts.Length == 2) {
var obj = new CustomProperty4();
obj.Property1 = parts[0];
obj.Property2 = parts[1];
return obj;
}
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
if (value is CustomProperty4 && destinationType == typeof(string)) {
var obj = (CustomProperty4)value;
return obj.Property1 + ";" + obj.Property2;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
TypeConverter 處理複雜類型的序列化/反序列化,避免手工字串拼接。[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 讓設計器正確持久化子屬性。Render 階段透過 TypeDescriptor.GetConverter 統一輸出,保持一致性。TypeConverter 不僅簡化了 ViewState 中自定義類型的存取,還能無縫整合至設計時環境,是 ASP.NET 控件開發中不可或缺的基礎設施。