轉帖|其它|編輯:郝浩|2009-04-02 09:34:34.000|閱讀 328 次
概述:前幾篇文章寫了有關視圖的知識,也講述了如何實現IStateManager接口。本篇將講解如何實現自定義轉換器。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
前言:之前幾篇文章寫了有關視圖的知識,也講述了如何實現IStateManager接口。本篇將講解如何實現自定義轉換器。當然了,有大量的代碼演示!本篇算是有關視圖機制的終結篇,還會講解有關ControlStatel控件狀態的實現。
有個小插曲,其實之前我已經把文章寫了一大半,不知道怎么回事,IE出了問題,自動關閉了,真是心痛阿,現在得重寫一遍。我想每個寫博文的朋友都有這樣的經歷吧,寫一篇文章真的很不容易!
在上篇中,我們講解了如何在一個自定義控件中保存自定義類的屬性,我現在再次把代碼貼出來,免得大家去翻頁。
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace CustomComponents
{
/**//**//**//**//**//**//**//// <summary>
///MyLogin 的摘要說明
/// </summary>
public class MyLogin:WebControl
{
屬性屬性屬性屬性
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Table;
}
}
protected override void RenderContents(HtmlTextWriter writer)
{
//顯示用戶名
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(UserName);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Id, "txtUserName");
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
//顯示用戶密碼
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(UserPassword);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Id, "txtPassword");
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
//顯示登錄按鈕
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Id, "btnSubmit");
writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
writer.AddAttribute(HtmlTextWriterAttribute.Value, "Login");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
}
}
上面的代碼開發了一個類似與Login的控件,然后我們也開發一個自定義的Person類:如下:
然后我們使得Login控件有一個Person類型的屬性(上面的代碼沒有寫出來,但是大家要知道),用來保存一些其他的用戶信息,而且我們還讓Person類實現了IStateManager接口,用來在保存自身的狀態。(大家不清楚,最好可以先看看之前的一篇文章)。
其實使得自定義類保存狀態的方法除了實現IStateManager接口之外,還有其他的方法,如本篇要講述的實現繼承自TypeConvert的自定義類型轉換器。
在.NET中要做一件事,其實有很多不同的解決的方法。
下面我們就來看看,我們怎么來實現自定義的轉換器。
其實實現一個自定義的類型轉換器不難,簡單的說就是:繼承TypeConvert,然后重寫幾個方法就OK,而且重寫方法的套路很固定,和之前實現IStateManager接口的一樣,很多時候可以照搬套用。
下面就來看看我們要重寫的四個方法,一一講解:
public virtual bool CanConvertFrom(ITypeDescriptorContext context,Type sourceType)
public override bool CanConvertTo(ITypeDescriptorContext context,Type destinationType)
上面兩個方法看起來很“對稱”。實現起來也不難。
我們知道我們的狀態機制基本可以理解為:從服務器把一些狀態序列化為字符串然后發送到客戶端,之后客戶端把狀態有回傳到服務器,服務器然后反序列化那些保存狀態的字符串,然后把這些狀態還原,然后再賦給新的對象。
所以上面兩個方法就不難理解了:
CanConvertFrom方法就是判斷客戶端到服務器的字符串是否可以被還原轉換為對應的類型。本例中就是判斷客戶端發送的狀態字符串是否可以轉換為Person對象的實例。
同理了,CanConvertTo就是判斷服務器的Person的狀態是否可以轉換為字符串了。
下面就來看看另外的兩個方法:
public override object ConvertFrom(ITypeDescriptorContext context,CultureInfo culture, object value)
public override object ConvertTo(ITypeDescriptorContext context,CultureInfo culture, object value, Type destinationType)
和之前的理解一樣,這個兩個方法就是實際用來轉換的,ConvertForm就是把客戶端發送來的狀態字符串還原對應的類型,ConvertTo就是把服務器端的Person狀態轉換為字符串。
下面就實際的動手來實現自定義的轉換器CustomPersonConverter,繼承自TypeConvert;
public class CustomPersonConverter:TypeConvert
我們自定義的轉換器實際上就是用來把Person類進行轉換的,為了使得例子更加的實際一點,我們在Person中多添加一個屬性,代碼如下:
public class Person
{
private string address;
public string Address
{
get{return address;}
set{address=value;}
}
private string cardNum;
public string CardNum
{
get{return cardNum;}
set{cardNum=value;}
}
}
下面就開始重寫上面的四個方法,一點都不難,很多的代碼可以套用的:
public override bool CanConvertFrom(ITypeDescriptorContext context,Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
上面的代碼就是判斷,sourceType就是從客戶端發來的狀態字符串。
public override bool CanConvertTo(ITypeDescriptorContext context,Type destinationType)
{
if (destinationType == typeof(string))
return true;
return base.CanConvertTo(context, destinationType);
}
上面代碼中的destinationType在本例中就是Person類最后轉換成的字符串。
可以說上面兩個方法在任何實現TypeConvert的自定義轉換器中的寫法一樣的,套用就行了。
實際起作用的是后面的兩個方法,也很好寫的。
public override object ConvertTo(ITypeDescriptorContext context,CultureInfo culture, object value, Type destinationType)
{
if (value != null && !(value is DefaultTemplateManager2))
throw new ArgumentException();
if (destinationType == typeof(string))
{
if (value == null)
return string.Empty;
Person myPerson= value as Person;
string ss = string.Join(“,”,
new string[] {
myPerson.Address,
myPerson.CardNum
});
return ss;
}
return base.ConvertTo(context, culture, value, destinationType);
}
上面的方法實際上就是把Person的一個實例myPerson轉換為字符串,之后就發送給客戶端的。
public override object ConvertFrom(ITypeDescriptorContext
context,CultureInfo culture, object value)
{
if (value == null)
return new DefaultTemplateManager2();
string svalue = value as string;
if (svalue == null)
return base.ConvertFrom(context, culture, value);
string[] myPersonString= svalue.Split(new char[] { ‘,’ });
if (templateTypes.Length != 2)
throw new ArgumentException();
Person myPerson=new Person();
myPerson.Address=myPersonString[0];
myPeron.CardNum=myPersonString[1];
return myPerson;
}
上面的代碼就是重建myPerson對象。
到這里我們的自定義的轉換器類就完成了。大家也看到了開發不是很難。
下面我們就來看看怎么用這個自定義轉換器。
首先,在我們的Person類上加上如下Attribute:
因為在Login控件中有一個類型為Person的屬性PersonInfo,如下:
然后再在Login控件中重寫幾個方法就OK,和上一篇差不多的,如下:
protected override void TrackViewState()
{
if( personInfo!= null)
{
TypeConverter converter = TypeDescriptor.GetConverter(personInfo!);
if (converter.CanConvertTo(typeof(string)))
{
string svalue = (string)converter.ConvertTo(personInfo,typeof(string));
ViewState[“PersonInfo”] = svalue;
}
}
base.TrackViewState();
}
protected override object SaveViewState()
{
if (personInfo!= null)
{
TypeConverter converter = TypeDescriptor.GetConverter(personInfo);
if (converter.CanConvertTo(typeof(string)))
{
string newValue = (string)converter.ConvertTo(personInfo,
typeof(string));
string oldValue = (string)ViewState[“PersonInfo”];
if (newValue != oldValue)
ViewState[“PersonInfo”] = newValue;
}
}
return base.SaveViewState();
}
protected override void LoadViewState(object savedState)
{
string svalue = ViewState[“PersonInfo”] as string;
if (svalue != null)
{
TypeConverter converter =
TypeDescriptor.GetConverter(typeof(Person));
if (converter.CanConvertFrom(typeof(string)))
personInfo=(Person)converter.ConvertFrom(svalue);
}
else
base.LoadViewState(savedState);
}
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園