top
Loading...
ASP.NET2.0服務器控件之類型轉換器
教程推薦
·ASP.NET初學者入門實踐
·Visual Baisc.NET入門
·基于C#的接口基礎教程
·Visual Studio 2005
精彩專題
·ASP.NET創建XML Web服務
·Visual Basic 9.0新功能
·VB2005實現RSS覽盡天下事
主題社區
·ASP.NET源碼·ASP.NET

類型轉換器是實現自定義服務器控件屬性過程中比較重要的內容。本文將對類型轉換器的基本概念和實現方法進行介紹。

1. 類型轉換器基本概念

類型轉換器是自定義服務器控件的輔助性功能實現。它主要用于執行從字符串表示形式到指定類型之間的雙向轉換。例如,以文本形式表示屬性值,將用戶輸入的文本轉換為相應數據類型等等,都應用了類型轉換器。

對于多數基本數據類型(如Int32、Bool、Char、String、枚舉類型等),.NET框架已經為它們提供了默認的類型轉換器,這些類型轉換器完成從字符串到相關值的轉換并執行驗證檢查的功能。默認的類型轉換器派生自System.ComponentModel.TypeConverter類,名為TypeConverterNameConverter。例如,當開發人員在*.aspx文件中設置服務器控件屬性時會發現,某些屬性值為基本類型,即Bool、Char、Enum、Int等,但是,一律被設置為String類型,這就牽扯到一個類型轉換的問題。例如,屬性Height="150px",屬性值"150px"在設置時是String類型,而這里的屬性值應當作為Unit類型,那么所面臨的問題就是必須要求頁面編譯器將字符串"150px"轉換為Unit類型。通常情況下,對于屬性值為基本類型的屬性,頁面編譯器將自動應用相關的類型轉換器完成轉換工作。在剛才的例子中,頁面編譯器將自動調用類型轉換器System.Web.UI.WebControls.UnitConverter完成String類型與Unit類型之間的相互轉換。

然而,上面的方法只能解決少數比較簡單的類型轉換問題,并且在多數情況下,相關的類型轉換過程都是默認自動完成的。當默認類型轉換器無法滿足需要時,例如,對于復雜屬性的情況,是沒有關聯的默認類型轉換器時,則可以通過實現自定義類型轉換器來實現。

自定義類型轉換器是本文的重點內容。按照自定義類型轉換器的功能分類,可以將自定義類型轉換器分為3種:

· 值翻譯的類型轉換器;

這種類型轉換器最為常見,它主要完成從字符串到值得轉換,或用于在設計時和運行時進行數據類型之間的雙向翻譯。例如,實現從String類型轉換為表示在二維平面中定義點的、整數X和Y坐標的有序對Point類型,或者從Point類型轉換為String類型。此處的String類型與Ponit類型之間的雙向轉換,則需要實現一個值翻譯的類型轉換器。

· 向屬性窗口提供標準值列表的類型轉換器;

在Visual Studio 2005中包括控件屬性窗口。類型轉換器可以為屬性窗口中控件的類型提供一個值列表。當開發人員單擊值列表時,則可以方便的在下拉列表中設置屬性的值。

· 在運行時為屬性初始化生成代碼的類型轉換器;

.NET Framework 提供了在設計時生成動態屬性初始化代碼(此代碼在運行時初始化屬性)的功能。開發人員可以構建一個產生基于構造函數的初始化代碼的類型轉換器。為了在運行時配置類型屬性,這些類型轉換器可以使用在設計時設置的值來動態生成構造函數代碼。類型轉換器實現邏輯以配置屬性的類型和構造函數的值。

實現以上3種類型轉換器都要求自定義類型轉換器的類必須繼承自System.ComponentModel.TypeConverter基類,或者TypeConverter類的已有子類。下面簡單介紹一下TypeConverter及其子類的基本情況。

TypeConverter類主要提供了一種將值的類型轉換為其他類型,以及訪問標準值和子屬性的統一方法。該類包括多個成員方法。對于創建自定義類型轉換器而言,讀者應了解以下幾個常見方法:

(1)CanConvertFrom方法:返回該轉換器是否可以將一種類型的對象轉換為此轉換器的類型。

(2)ConvertFrom方法:將給定值轉換為此轉換器的類型。

(3)CanConvertTo方法:返回此轉換器是否可將該對象轉換為指定的類型。

(4)ConvertTo方法:將給定值對象轉換為指定的類型。

(5)IsValid方法:返回給定值對象對于此類型是否有效。

(6)GetStandardValuesSupported方法:返回此對象是否支持可以從列表中選取的標準值集。

(7)GetStandardValues方法:返回此類型轉換器設計用于的數據類型的標準值集合。

TypeConverter類是實現類型轉換器的基礎。為了支持默認類型轉換功能,ASP.NET 2.0還對TypeConverter類進行了擴展,其內置了多個派生類。例如,CharConverter、DateTimeConverter、ExpandableObjectConverter、EnumConverter等。它們在完成類型轉換的同時,還可以幫助開發人員創建自定義類型轉換器,例如,可創建繼承自ExpandableObjectConverter類的類型轉換器,該基類提供了在可擴展對象與其他各種表示形式之間實現轉換的類型轉換器。這樣就可以簡化(相對于從TypeConverter基類)創建類型轉換器的過程。

另外,在使用已有類型轉換器過程要注意:無論何時都不要直接訪問類型轉換器。而應通過使用TypeDescriptor調用適當的轉換器。

當實現類型轉換器之后,可以使用如下方法應用類型轉換器。

[TypeConverter(typeof(MyClassConverter))]
public class MyClass {
// Insert code here.
}

以上代碼顯示了類型轉換器的應用方法。其通知MyClass使用名為MyClassConverter的類型轉換器。此示例假定已在其他位置實現了MyClassConverter。在應用過程中需要注意,元數據屬性TypeConverter通常應用于復雜屬性或數據成員,以將其與類型轉換器關聯。如果將TypeConverter應用于類型,則不必將其再次應用于該類型的屬性或數據成員。

軟件頻道精品推薦

更多精彩
點擊體驗>>

2. 值翻譯的類型轉換器

值翻譯的類型轉換器主要完成屬性值類型與String類型之間的相互轉換功能。為了實現這個類型轉換器,開發人員可使類型轉換器類自TypeConverter基類派生,并且重寫其中的多個方法。請看下面的實例。

下面的代碼實現一個類型轉換器類PointConverter,它將String類型轉換為System.Drawing.Point類型,將System.Drawing.Point類型轉換為String類型。

using System;
using System.ComponentModel;
using System.Globalization;
using System.Drawing;
// 實現類型轉換器的類應繼承自TypeConverter類
public class PointConverter : TypeConverter{
// 重寫CanConvertFrom方法
public override bool CanConvertFrom(ITypeDescriptorContext context,Type sourceType) {
if (sourceType == typeof(string)) {
return true;
}
return base.CanConvertFrom(context, sourceType);
}
// 重寫ConvertFrom方法
public override object ConvertFrom(ITypeDescriptorContext context,CultureInfo culture, object value) {
if (value is string) {
string[] v = ((string)value).Split(new char[] {','});
return new Point(int.Parse(v[0]), int.Parse(v[1]));
}
return base.ConvertFrom(context, culture, value);
} // 重寫ConvertTo方法
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
if (destinationType == typeof(string)) {
return ((Point)value).X + "," + ((Point)value).Y;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}

上面的代碼展示了典型的值翻譯類型轉換器的創建方法。本例中主要重寫了TypeConverter類的4個方法。

(1)定義從System.ComponentModel.TypeConverter派生的類PointConverter;

(2)重寫CanConvertFrom方法,指定轉換器可將String類型轉換為Point類型,并調用基類實現;

(3)重寫ConvertFrom方法,指定將String類型轉換為Point類型的具體實現方法,并調用基類實現;

(4)重寫ConvertTo方法,指定將Point類型轉換為String類型的具體實現方法,并調用基類實現;

實際上,在通常情況下,對于實現值翻譯的類型轉換器除需重寫上述4個TypeConverter類成員方法之外,還需要重寫CanConvertTo和IsValid方法。注意:如果是轉換為String類型,則不需要重寫該方法。在上面的代碼中,是轉換將Point類型轉換為String類型,因此不重寫CanConvertTo方法。同時,本例中無需驗證,因此沒有重寫IsValid方法。

值翻譯的類型轉換器在控件開發中應用廣泛。很多情況下,控件開發人員可能忘記創建轉換器而導致控件無法編譯,出現一些莫明其妙的錯誤,因此建議讀者仔細體會,重點掌握。

3. 向屬性窗口提供標準值列表的類型轉換器

類型轉換器可以為Visual Studio 2005的屬性窗口中的屬性值輸入字段,提供一個標準值列表,那么當在屬性瀏覽器中選中了與該類型轉換器關聯的類型屬性時,值輸入字段將包含一個按鈕,該按鈕顯示屬性類型的標準值下拉列表,可從中選擇標準值。

實現在屬性窗口中提供標準值下拉列表的類型轉換器有以下6個步驟:

(1)定義從System.ComponentModel.TypeConverter派生的類;

(2)重寫GetStandardValuesSupported方法并返回true;

(3)重寫GetStandardValues方法并返回包含屬性類型標準值的StandardValuesCollection。屬性類型的標準值必須是類型字符串;

(4)重寫CanConvertFrom方法并為類型字符串的sourceType參數值返回true;

(5)重寫ConvertFrom方法并基于"值"參數返回相應的屬性值;

(6)將指示類型轉換器類型的TypeConverterAttribute應用于要為其提供一組標準值的類型。

限于篇幅,本文將不再列舉代碼示例。關于實現過程中的方法應用,讀者可參考前文相關內容或者MSDN。

4. 在運行時為屬性初始化生成代碼的類型轉換器

.NET框架中提供了在設計時生成可動態配置的屬性初始化代碼(此代碼在運行時初始化屬性)的功能。開發人員可以構建一個產生基于構造函數的初始化代碼的類型轉換器。為了在運行時配置類型屬性,這些類型轉換器可以使用在設計時設置的值來動態生成構造函數代碼。類型轉換器實現邏輯以配置屬性的類型和構造函數的值。

為了初始化屬性,除了生成構造函數之外,如果您還需要生成代碼,可以實現一個自定義的CodeDomSerializer,并應用將類型的CodeDomSerializer與該類型關聯的 DesignerSerializerAttribute,這樣就可以動態地生成代碼。通常只有在對組件初始化的代碼生成進行動態控制或自定義很重要的情況下,才使用這種方法。要生成自定義的基于構造函數的屬性初始化程序,必須將類型轉換器與屬性的類型關聯來進行初始化,而且該類型轉換器必須能夠轉換到InstanceDescriptor。

實現生成基于構造函數的屬性初始化代碼的類型轉換器有3個步驟:

(1)定義從System.ComponentModel.TypeConverter派生的類;

(2)重寫CanConvertTo方法。如果destinationType 參數等于InstanceDescriptor類型,返回true;

(3)重寫ConvertTo方法。如果destinationType參數等于InstanceDescriptor 類型,構造并返回一個InstanceDescriptor,表示要為之生成代碼的構造函數和構造函數參數。要創建表示相應構造函數及參數的InstanceDescriptor,可通過使用您所查找的構造函數的相應方法簽名來調用GetConstructor或GetConstructors方法,從要初始化的屬性的Type中獲取ConstructorInfo。然后創建一個新的實例說明符,并為表示待用構造函數類型的類型傳遞ConstructorInfo,同時傳遞與構造函數簽名匹配的參數對象數組;

5. 小結

本文主要介紹了類型轉換器的基本概念以及3種類型轉換器的實現方法。尤其需要讀者關注的是其中的值翻譯的類型轉換器,這是作為開發人員應重點掌握的內容。
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗