版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Asp.Net 2.0 中的頁(yè)生命周期與自定義用戶(hù)控件開(kāi)發(fā)2007/10/25摘要:Asp.Net2.0提供自定義用戶(hù)開(kāi)發(fā)的程序架構(gòu),基于該架構(gòu)可以開(kāi)發(fā)出滿(mǎn)足用戶(hù)特殊需求的各種可重用的控件。自定義控件的開(kāi)發(fā)同樣要遵循頁(yè)生命周期的規(guī)律。在Asp.Net 2.0 中引入控件狀態(tài),以防止因關(guān)閉視圖狀態(tài),而控件無(wú)法正常工作的現(xiàn)象。關(guān)鍵詞:ASP.Net;頁(yè)生命周期(Page Life Cycle);自定義控件;控件狀態(tài)(View State)1.引述12.自定義控件的編程模型12.1.Net自定義控件開(kāi)發(fā)靜態(tài)模型12.2.簡(jiǎn)單呈現(xiàn)自定義控件的開(kāi)發(fā)22.3.復(fù)合自定義控件的開(kāi)發(fā)53.自定義控件的頁(yè)生命周
2、期83.1.事件方法的調(diào)用順序83.2.控件狀態(tài)103.3.動(dòng)態(tài)創(chuàng)建控件134.自定義控件的開(kāi)發(fā)原則145.結(jié)束語(yǔ)15參考文獻(xiàn)151. 引述在上一篇關(guān)于頁(yè)生命周期的文章中重點(diǎn)介紹了頁(yè)生命周期的基本概念,并給出了基本的頁(yè)面編程規(guī)則。本篇文章則從自定義用戶(hù)控件開(kāi)發(fā)的角度進(jìn)一步深入闡述頁(yè)生命周期的問(wèn)題,并且也給出開(kāi)發(fā)自定義控件的一些基本編程規(guī)則以供參考。但是本篇文章并不闡述自定義控件的所有內(nèi)容,有關(guān)這方面的完整幫助參見(jiàn)參考文獻(xiàn)1。2. 自定義控件的編程模型2.1. .Net自定義控件開(kāi)發(fā)靜態(tài)模型自定義控件與Web用戶(hù)控件類(lèi)似,是頁(yè)面組件重用的一種機(jī)制,但是它不同于Web用戶(hù)控件,它提供了比Web用戶(hù)
3、控件更強(qiáng)的設(shè)計(jì)時(shí)支持和實(shí)現(xiàn)與部署策略。但是自定義控件并不提供可視化的編程模型,.Net框架提供基于繼承方式的編程模型。從.Net框架提供的自定義控件的靜態(tài)模型來(lái)看,主要涉及到WebControl、CompositeControl兩個(gè)重要的基類(lèi),而這兩個(gè)基類(lèi)都派生自Control基類(lèi)。WebControl主要提供編寫(xiě)Web自定義控件需要公共屬性、方法,CompisteControl是.Net2.0中為簡(jiǎn)化復(fù)合自定義控件編程工作而提供的基類(lèi),它同時(shí)又是從WebControl派生出來(lái)的子類(lèi),并且實(shí)現(xiàn)了INamingContainer,ICompositeControlDesignAccessor兩個(gè)
4、接口,以方便子控件的自治地唯一命名(UniqueID),以及使復(fù)合控件設(shè)計(jì)器可以在設(shè)計(jì)時(shí)重新創(chuàng)建其關(guān)聯(lián)控件的子控件。下圖表示了主要的Web自定義控件的靜態(tài)模型。System.Web.UI.ControlSystem.Web.UI.WebControls.WebControlSystem.Web.UI.WebControls.CompositeControlINamingContainer自定義控件開(kāi)發(fā)無(wú)界面控件開(kāi)發(fā)簡(jiǎn)單界面控件開(kāi)發(fā)復(fù)合控件圖 1 自定義控件開(kāi)發(fā)的靜態(tài)編程模型如果開(kāi)發(fā)的是沒(méi)有用戶(hù)界面的自定義控件,自定義控件類(lèi)直接從Control派生即可,如果開(kāi)發(fā)的具有簡(jiǎn)單界面形式,一般這種控件最
5、后呈現(xiàn)為一個(gè)Html標(biāo)記,則需要從WebControl派生,而如果開(kāi)發(fā)的自定義控件是由已經(jīng)存在的其他控件組合而成,則需要派生自CompositeControl。而在派生不同的類(lèi)之后,還需要去重寫(xiě)一些基類(lèi)方法和屬性,以保證自定義控件的正常工作。下表給出了基本派生原則。表 1 自定義控件基本派生原則派生類(lèi)原則需要重寫(xiě)的基類(lèi)方法需要重寫(xiě)的基類(lèi)屬性Control無(wú)界面呈現(xiàn)。WebControl呈現(xiàn)為單一Html標(biāo)記。RenderContents/RenderTagKey.getCompositeControl由其他控件組合而成,呈現(xiàn)為眾多復(fù)雜的Hmtl標(biāo)記。RecreateChildControlsC
6、reateChildControlsRender對(duì)于其他可以重寫(xiě)的方法和屬性則根據(jù)實(shí)際需要確定是否重寫(xiě)。如,對(duì)于派生自WebControl的簡(jiǎn)單自定義控件,可以重寫(xiě)方法“AddAttributesToRender”以增加呈現(xiàn)為Html標(biāo)記后的標(biāo)記屬性(Attribute)。2.2. 簡(jiǎn)單呈現(xiàn)自定義控件的開(kāi)發(fā)下面定義一個(gè)類(lèi)MailLink是一個(gè)呈現(xiàn)為電子郵件地址的簡(jiǎn)單控件的實(shí)現(xiàn),它派生自WebControl基類(lèi)。代碼 1 MailLink的實(shí)現(xiàn)代碼 / <summary> / 用于構(gòu)造郵件地址的控件。 / </summary> DefaultProperty("
7、Text") ValidationProperty("EMail") ParseChildren(true, "Text") System.Drawing.ToolboxBitmap(typeof(MailLink), "MailLink.bmp") ToolboxData("<0:MailLink runat="server"></0:MailLink>") public class MailLink : WebControl private const st
8、ring _defaultText = "郵件地址" / <summary> / 郵件地址的顯示文本。 / </summary> Bindable(true) Category("外觀") DefaultValue(_defaultText) PersistenceMode(PersistenceMode.InnerDefaultProperty) Localizable(true) Description("顯示為文本。") public virtual string Text get String s =
9、(String)ViewState"Text" return (s = null) ? _defaultText : s); set ViewState"Text" = value; / <summary> / 郵件地址,以“mailto:”開(kāi)始。 / </summary> Bindable(true) Category("數(shù)據(jù)") DefaultValue("exapmle") Localizable(true) Description("E-Mail鏈接地址。") p
10、ublic virtual string EMail get String s = (String)ViewState"EMail" return (s = null) ? "exapmle" : s); set ViewState"EMail" = value; / <summary> / 重寫(xiě)屬性。 / </summary> protected override HtmlTextWriterTag TagKey get return HtmlTextWriterTag.A; / <summary>
11、; / 重寫(xiě)方法。 / </summary> / <param name="writer"></param> protected override void AddAttributesToRender(HtmlTextWriter writer) base.AddAttributesToRender(writer); writer.AddAttribute(HtmlTextWriterAttribute.Href, "mailto:" + EMail); / <summary> / 重寫(xiě)方法。 / <
12、/summary> / <param name="output"></param> protected override void RenderContents(HtmlTextWriter output) if (String.IsNullOrEmpty(Text) Text = EMail; output.Write(Text); 上述代碼中,定義了兩個(gè)屬性“Text”和“EMail”分別表示電子郵件地址的現(xiàn)實(shí)文本和地址本身的鏈接,這兩個(gè)屬性都被保存在視圖狀態(tài)中。重寫(xiě)的屬性為“TagKey”,將該自定義控件呈現(xiàn)為“HtmlTextWrite
13、rTag.A”枚舉定義的Html的標(biāo)記“<a>”。重寫(xiě)的方法有兩個(gè),其中“RenderContents”用于將屬性“Text”呈現(xiàn)為Html標(biāo)記內(nèi)包含的文字,而“AddAttributesToRender”用于為呈現(xiàn)的Html標(biāo)記加上屬性(Attribute)。該控件最終呈現(xiàn)的Html為:代碼 2 MailLink 自定義控件最終呈現(xiàn)的Html<a href=”mailto:example”>郵件地址</a>雖然對(duì)于簡(jiǎn)單控件也可以直接重寫(xiě)“Render”方法完成所有的呈現(xiàn)工作,但是這種做法并不推薦。具體的代碼如下:代碼 3直接重寫(xiě)Render方法完成所有呈現(xiàn)
14、工作 protected override void Render(HtmlTextWriter output) output.Write(“<a href=mailto:” + EMail + “>” + Text + “</a>”; 2.3. 復(fù)合自定義控件的開(kāi)發(fā)而對(duì)于復(fù)合自定義控件則主要通過(guò)重寫(xiě)“Render”方法,對(duì)復(fù)合控件進(jìn)行呈現(xiàn)。具體的代碼可以參見(jiàn)“eSchool.Web.UI.WebControls”命名控件下的一些派生自“CompositeControl”的自定義復(fù)合控件的源碼。復(fù)合控件是由眾多的子控件組合而成的,“Render”方法只能用來(lái)呈現(xiàn)所有子控
15、件,但是創(chuàng)建子控件的任務(wù)則是由“CreateChildControls”和“RecreateChildControls”方法來(lái)實(shí)現(xiàn)的,因此需要重寫(xiě)這兩個(gè)重要的方法。如果將上述的MailLink自定義控件改造為一個(gè)符合控件,則具體的代碼如下:代碼 4改造為復(fù)合自定義控件的MailLink實(shí)現(xiàn) / <summary> / 用于構(gòu)造郵件地址的控件。 / </summary> DefaultProperty("Text") ValidationProperty("EMail") ParseChildren(true, "Text
16、") System.Drawing.ToolboxBitmap(typeof(MailLink), "MailLink.bmp") ToolboxData("<0:MailLink runat="server"></0:MailLink>") public class MailLink : CompositeControl private const string _defaultText = "郵件地址" / <summary> / 郵件地址的顯示文本。 / <
17、/summary> Bindable(true) Category("外觀") DefaultValue(_defaultText) PersistenceMode(PersistenceMode.InnerDefaultProperty) Localizable(true) Description("顯示為文本。") public virtual string Text get String s = (String)ViewState"Text" return (s = null) ? _defaultText : s); s
18、et ViewState"Text" = value; / <summary> / 郵件地址,以“mailto:”開(kāi)始。 / </summary> Bindable(true) Category("數(shù)據(jù)") DefaultValue("exapmle") Localizable(true) Description("E-Mail鏈接地址。") public virtual string EMail get String s = (String)ViewState"EMail&quo
19、t; return (s = null) ? "exapmle" : s); set ViewState"EMail" = value; / <summary> / 定義子控件。 / </summary> HyperLink _hyperLnkEmail; / <summary> / 重寫(xiě)方法屬性。 / </summary> protected override void RecreateChildControls() EnsureChildControls(); / <summary> / 重
20、寫(xiě)方法。 / </summary> protected override void CreateChildControls() this.Controls.Clear(); _hyperLnkEmail = new HyperLink(); _hyperLnkEmail.ID = "hyperLnkEmail" _hyperLnkEmail.Text = this.Text; _lnkBtnFirst.NavigateUrl = "mailto:" + this.EMail; this.Controls.Add(_hyperLnkEmail)
21、; / <summary> / 重寫(xiě)方法。 / </summary> / <param name="writer"></param> protected override void Render (HtmlTextWriter writer) this.AddAttributesToRender(writer); writer.RenderBeginTag(HtmlTextWriterTag.Table); writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.RenderBe
22、ginTag(HtmlTextWriterTag.Td); _lnkBtnFirst.RenderControl(writer); writer.RenderEndTag(); writer.RenderEndTag(); writer.RenderEndTag(); 從上述代碼可以看出,變化主要在以下幾點(diǎn):(1) 需要派生自基類(lèi)“CompositeControl”。(2) 需要將自控件定義為自定義控件的成員變量,如:“HyperLink _hyperLnkEmail;”。(3) 需要重寫(xiě)方法“RecreateChildControls”,在該方法中調(diào)用“EnsureChildControls
23、”方法,確保自定義控件是否包含子控件,如果不包含,則創(chuàng)建子控件。(4) 需要重寫(xiě)方法“CreateChildControls”,實(shí)例化子控件,并設(shè)置子控件的屬性。(5) 需要重寫(xiě)方法“Render”,以呈現(xiàn)自定義控件,包括對(duì)子控件的呈現(xiàn)。在該過(guò)程中請(qǐng)注意以下幾點(diǎn):(1) 在重寫(xiě)“CreateChildControls”方法的時(shí)候,首先需要將當(dāng)前自定義控件的子控件集合清空,即調(diào)用語(yǔ)句“this.Controls.Clear()”,在將子控件實(shí)例化之后,需要將子控件添加到自定義控件的子控件集合中,即調(diào)用語(yǔ)句“this.Controls.Add(_hyperLnkEmail)”。如果不清空子控件集合
24、,則在自定義控件重新創(chuàng)建的時(shí)候會(huì)因?yàn)橐晥D狀態(tài)而保留上次的結(jié)果,并重復(fù)添加自控件。如果不將子控件添加到自定義控件子控件集合中,雖然能正常呈現(xiàn)子控件,但無(wú)法響應(yīng)子控件的服務(wù)器事件。(2) 在重寫(xiě)“Render”方法的時(shí)候,需要首先應(yīng)用Html標(biāo)記屬性(Attribute)呈現(xiàn),即調(diào)用語(yǔ)句“this.AddAttibutesToRender(writer)”,以便能夠?qū)ψ远x控件應(yīng)用樣式和皮膚。(3) 對(duì)自定義控件的呈現(xiàn)的時(shí)候,推薦使用“堆棧方式”呈現(xiàn)。上述代碼中的“writer.RenderBeginTag(HtmlTextWriterTag.Table)”即向呈現(xiàn)堆棧中送入了Html標(biāo)記“<
25、;Table>”,接著使用“writer.RenderBeginTag(HtmlTextWriterTag.Tr)”進(jìn)一步送入“<Tr>”標(biāo)記,然后在呈現(xiàn)完對(duì)應(yīng)的控件之后,調(diào)用若干出棧呈現(xiàn)語(yǔ)句“writer.RenderEndTag()”,以呈現(xiàn)Html的結(jié)束標(biāo)記“</Table>”等。由于采用棧方式,因此在出棧呈現(xiàn)的時(shí)候,無(wú)須指明呈現(xiàn)的Html標(biāo)記。這樣處理的好處在于代碼結(jié)構(gòu)較好,并且Html標(biāo)記可以被Asp.Net框架識(shí)別在不同瀏覽器中按照相關(guān)特性進(jìn)行呈現(xiàn)。(4) 子控件的呈現(xiàn)很簡(jiǎn)單,只需要調(diào)用子控件的方法“RenderControl”即可完成。3. 自定義控
26、件的頁(yè)生命周期自定義控件同樣遵循Asp.Net框架對(duì)頁(yè)生命周期的處理,與Web用戶(hù)控件相比較,除了關(guān)心主要事件方法在一次頁(yè)生命周期中的調(diào)用順序之外,還需要了解一些被重寫(xiě)的方法在一次頁(yè)生命周期中被調(diào)用的時(shí)機(jī)。只有了解它們被調(diào)用的順序之后,才能正確地處理自定義控件的編程問(wèn)題。3.1. 事件方法的調(diào)用順序圖2給出了以復(fù)合自定義控件為例的一次頁(yè)生命周期的方法調(diào)用順序。從圖中可以看出,自定義控件的事件方法與Web用戶(hù)控件一致,但是由于自定義控件的編程環(huán)境不是在Asp.Net的頁(yè)面設(shè)計(jì)環(huán)境中,因此編寫(xiě)自定義控件的事件方法時(shí),只需要重寫(xiě)相關(guān)事件方法即可,如:“OnInit”、“OnLoad”、“OnPreR
27、ender”、“OnUnload”。在自定義控件的頁(yè)生命周期中,有以下幾點(diǎn)需要關(guān)注:(1) “CreateChildControls”方法的調(diào)用相對(duì)比較特殊,雖然在圖 中出現(xiàn)了兩次該方法的調(diào)用,但是在運(yùn)行時(shí),是在不同時(shí)間內(nèi)被調(diào)用的獨(dú)立兩次,在一次頁(yè)生命周期中,仍然是只被調(diào)用一次。區(qū)別就在于當(dāng)頁(yè)請(qǐng)求為初次頁(yè)請(qǐng)求的時(shí)候,該方法將被Asp.Net框架在頁(yè)的“Page_PreRender”事件方法被執(zhí)行之后才被調(diào)用。但是當(dāng)回發(fā)頁(yè)請(qǐng)求的時(shí)候,由于頁(yè)生命周期需要在“Page_PreLoad”之前恢復(fù)所有控件的動(dòng)態(tài)頁(yè)視圖狀態(tài),因此需要在該事件方法被調(diào)用之前創(chuàng)建復(fù)合控件的子控件,以便恢復(fù)其動(dòng)態(tài)視圖狀態(tài)。(2)
28、 “Render”方法則是在“Page_SaveStateComplete”頁(yè)事件方法之后被調(diào)用的。(3) 如果自定義控件的“Visible”屬性被設(shè)置為“false”,則自定義控件的“OnPreRender”、“CreateChildControls”和“Render”方法將不會(huì)被調(diào)用。Page_PreInitPage_InitPage_InitCompletePage_PreLoadPage_LoadControl PostBack EventPage_LoadCompletePage_PreRenderData Bound EventPage_PreRenderCompletePage_
29、SaveStateCompletePage_UnloadOnInitOnLoadControl PostBack EventOnPreRenderOnUnload頁(yè)事件復(fù)合自定義控件事件/方法Page ValidControl ValidCreateChildControlsCreateChildControlsRender圖 2 頁(yè)面與復(fù)合自定義控件事件及調(diào)用順序3.2. 控件狀態(tài).Net2.0中增加了控件狀態(tài)的概念,它不同于視圖狀態(tài),控件狀態(tài)不會(huì)隨頁(yè)面或控件的視圖狀態(tài)的關(guān)閉而丟失,以控件狀態(tài)保存的屬性值將會(huì)強(qiáng)制保存在視圖狀態(tài)承載的隱藏域中,在每次回發(fā)請(qǐng)求的過(guò)程中都會(huì)被恢復(fù)。這樣可以保證自定
30、義控件的關(guān)鍵屬性值不會(huì)因視圖狀態(tài)被關(guān)閉而丟失,從而影響到控件的基本正常運(yùn)行。但是控件狀態(tài)不能大量存在,因?yàn)樗陧?yè)各請(qǐng)求期間總是存在,并且作為回發(fā)數(shù)據(jù)處理,會(huì)影響系統(tǒng)的系統(tǒng),應(yīng)該將關(guān)鍵性的控件屬性保存為控件狀態(tài)。在“eSchool.Web.UI.WebControls”命名空間中提供的很多復(fù)合控件是對(duì)外部控件進(jìn)行控制的自定義控件,如:“Paging”控件就是用來(lái)為“GridView”這樣支持分頁(yè)功能的控件提供更加豐富的分頁(yè)功能,它有一個(gè)屬性“ControlID”就是用來(lái)記錄需要控制分頁(yè)的外部控件的ID,如:某個(gè)頁(yè)面指定的“GridView”控件的ID。這樣的屬性如果在頁(yè)面回發(fā)請(qǐng)求過(guò)程中丟失,將會(huì)
31、造成“Paging”控件無(wú)法查找到需要控制分頁(yè)的外部控件,從而無(wú)法正常工作。代碼 5記錄為控件狀態(tài)的屬性 private string _controlId = string.Empty; / <summary> / 控制分頁(yè)的控件ID。 / </summary> Browsable(true) IDReferenceProperty TypeConverter(typeof(ControlIDConverter) DefaultValue("") Category("數(shù)據(jù)") Description("控制分頁(yè)的控件I
32、D。") public string ControlID get return _controlId; set _controlId = value; 上述代碼中,記錄為控件狀態(tài)的屬性,按照普通的屬性定義方法去封裝一個(gè)在自定義控件類(lèi)中定義的成員變量。為了將該屬性保存為控件狀態(tài)還需要在自定義控件的“OnInit”事件方法中用頁(yè)面對(duì)象的“RegisterRequiresControlState”方法將該自定義控件注冊(cè)為需要保存控件狀態(tài)的頁(yè)面控件,以通知頁(yè)面在保存狀態(tài)的時(shí)候,將需要保存為控件狀態(tài)的屬性保存到控件狀態(tài)中。代碼 6用“RegisterRequiresControlState”頁(yè)
33、面方法將當(dāng)前控件注冊(cè)為需要保存控件狀態(tài)的頁(yè)面控件 / <summary> / 重寫(xiě)OnInit方法,以響應(yīng)控件的Init事件,并將當(dāng)前控件注冊(cè)為需要頁(yè)面保存其控件狀態(tài)的頁(yè)面控件。 / </summary> / <param name="e"></param> protected override void OnInit(EventArgs e) base.OnInit(e); Page.RegisterRequiresControlState(this); InitControl(); 但是有上述代碼,還無(wú)法將“Control
34、ID”屬性保存在控件狀態(tài)中,還需要去重寫(xiě)兩個(gè)重要的基類(lèi)方法“SaveControlState”和“LoadControlState”。代碼 7保存和裝載控件狀態(tài)的代碼 / <summary> / 保存控件狀態(tài)。 / </summary> / <returns>需要保存的控件狀態(tài)對(duì)象。</returns> protected override object SaveControlState() System.Collections.ArrayList list = new System.Collections.ArrayList(); list.A
35、dd(base.SaveControlState();/保存基類(lèi)控件狀態(tài) list.Add(_controlId); return list; / <summary> / 在回發(fā)請(qǐng)求的時(shí)候去重新裝載控件狀態(tài)。 / </summary> / <param name="savedState">需要狀態(tài)的控件狀態(tài)。</param> protected override void LoadControlState(object savedState) if (savedState is System.Collections.Array
36、List) ArrayList list = savedState as ArrayList; if (list.Count >= 2) base.LoadControlState(list0);/恢復(fù)基類(lèi)控件狀態(tài) ControlID = (string)list1; else base.LoadControlState(savedState); “SaveControlState”重寫(xiě)方法是用來(lái)提供需要保存到控件狀態(tài)中的對(duì)象,“LoadControlState”重寫(xiě)方法則是從該方法的參數(shù)中恢復(fù)保存在控件狀態(tài)中的屬性值。由于控件狀態(tài)需要作為隱藏域來(lái)處理,因此保存在控件狀態(tài)中的屬性類(lèi)型需要
37、是可序列化的類(lèi)型。其中“SaveControlState”方法將在每次頁(yè)請(qǐng)求的“Page_SaveStateComplete”頁(yè)面事件之前被調(diào)用,而“LoadControlState”方法只在頁(yè)面回發(fā)請(qǐng)求中的“Page_PreLoad”頁(yè)面事件之前被調(diào)用。具體調(diào)用過(guò)程參見(jiàn)圖 。Page_PreInitPage_InitPage_InitCompletePage_PreLoadPage_LoadControl PostBack EventPage_LoadCompletePage_PreRenderData Bound EventPage_PreRenderCompletePage_SaveSt
38、ateCompletePage_UnloadOnInitOnLoadControl PostBack EventOnPreRenderOnUnload頁(yè)事件復(fù)合自定義控件事件/方法Page ValidControl ValidCreateChildControlsCreateChildControlsRenderSaveControlStateLoadControlState圖 3“SaveControlState”和“LoadControlState”方法在頁(yè)生命周期中的調(diào)用時(shí)機(jī)3.3. 動(dòng)態(tài)創(chuàng)建控件動(dòng)態(tài)創(chuàng)建控件是指在自定義控件中,或者是在頁(yè)面中,控件的個(gè)數(shù)或者類(lèi)型是隨著運(yùn)行時(shí)的要求而發(fā)生變
39、化的一種控件創(chuàng)建方式。在“eSchool.Web.UI.WebControls”命名空間中,用于執(zhí)行篩選的控件“Filtering”,其動(dòng)態(tài)增加和刪除條件構(gòu)造的過(guò)程即屬于動(dòng)態(tài)創(chuàng)建控件的過(guò)程。使用“Filtering”控件的執(zhí)行效果如圖。一組動(dòng)態(tài)創(chuàng)建的條件表達(dá)式構(gòu)造控件圖 4“Filtering”篩選控件動(dòng)態(tài)創(chuàng)建條件表達(dá)式構(gòu)造控件的運(yùn)行效果在“”控件中,用于構(gòu)造篩選條件的子控件是按照組的方式,被用戶(hù)在運(yùn)行的時(shí)候動(dòng)態(tài)構(gòu)造的。對(duì)于Asp.Net框架來(lái)說(shuō),如何保持上一次頁(yè)面請(qǐng)求過(guò)程中的這些動(dòng)態(tài)構(gòu)造的控件屬性是很關(guān)鍵的。這主要通過(guò)為每次動(dòng)態(tài)構(gòu)造的控件保持一個(gè)唯一不重復(fù)的“ID”屬性。Asp.Net框架按
40、照頁(yè)面每個(gè)控件的“ID”屬性在視圖狀態(tài)中尋找這些控件的上次頁(yè)請(qǐng)求保留下來(lái)的屬性值,并在當(dāng)前請(qǐng)求過(guò)程中恢復(fù)過(guò)來(lái)。因此,在為了做到這一點(diǎn),在自定義控件的“CreateChildControls”重寫(xiě)方法中要能為動(dòng)態(tài)構(gòu)造的控件恢復(fù)性的創(chuàng)建它們的“ID”屬性。具體代碼請(qǐng)參見(jiàn)“eSchool.Web.UI.WebControls.Filtering”控件的源代碼。下面的代碼是動(dòng)態(tài)創(chuàng)建條件表達(dá)式構(gòu)造控件的核心代碼。代碼 8動(dòng)態(tài)創(chuàng)建條件表達(dá)式構(gòu)造控件的核心代碼 private const string m_CriteriaNoListViewStateName = "CriteriaNoList&
41、quot; / <summary> / 為每一個(gè)篩選條件設(shè)置一個(gè)唯一的編號(hào),以便在回發(fā)請(qǐng)求的時(shí)候重構(gòu)篩選條件。 / </summary> Browsable(false) Description("記錄條件編號(hào)。") protected int CriteriaNoList get return Utility.GetViewStatePropertyValue<int>(this.ViewState, m_CriteriaNoListViewStateName, new int 0 ); set Utility.SetViewState
42、PropertyValue<int>(this.ViewState, m_CriteriaNoListViewStateName, value); / <summary> / 記錄在當(dāng)前頁(yè)請(qǐng)求周期中從條件編號(hào)列表中恢復(fù)過(guò)來(lái)的編號(hào)對(duì)應(yīng)的列表下標(biāo)。 / </summary> private int iCriteriaNo = 0; / <summary> / 構(gòu)造空白的篩選條件行。 / </summary> / <returns></returns> private TableRow ConstructBlankC
43、riteriaTableRow() int iCount = (iCriteriaNo > this.CriteriaNoList.Length - 1) ? Utility.GetMaxValue<int>(this.CriteriaNoList, 0) + 1 : this.CriteriaNoListiCriteriaNo; TableRow tblRow = new TableRow(); TableCell tblCell = new TableCell(); CheckBox chkBoxChooseOne = new CheckBox(); / 在此處需要位當(dāng)前
44、動(dòng)態(tài)創(chuàng)建的控件安置唯一的ID。 chkBoxChooseOne.ID = "chkBoxChooseOne" + iCount.ToString(); tblCell.Controls.Add(chkBoxChooseOne); tblRow.Cells.Add(tblCell); /其它動(dòng)態(tài)創(chuàng)建控件的代碼。 iCriteriaNo+; return tblRow; 上述代碼中使用了一個(gè)“CriteriaNoList”的屬性保存每次動(dòng)態(tài)創(chuàng)建的條件表達(dá)式的控件ID屬性的一個(gè)順序編碼,并且將其保存在視圖狀態(tài)中,以便下次頁(yè)請(qǐng)求的時(shí)候恢復(fù)過(guò)來(lái)。在“ConstructBlankCriteriaTableRow”方法中,為每個(gè)動(dòng)態(tài)創(chuàng)建的控件依照恢復(fù)過(guò)來(lái)的“CriteriaNoList”中的記錄恢復(fù)ID。由于動(dòng)態(tài)創(chuàng)建控件的問(wèn)題,關(guān)鍵在于控件的ID需要是唯一的。4. 自定義控件的開(kāi)發(fā)原則由于自定義控件對(duì)代碼編寫(xiě)能力和頁(yè)生命周期的理解要求較高,如果沒(méi)有處理好頁(yè)生命周期的問(wèn)題,很容易引發(fā)設(shè)計(jì)時(shí)和運(yùn)行的錯(cuò)誤,因此,需要有一個(gè)開(kāi)發(fā)指導(dǎo)性原則會(huì)幫助寫(xiě)出正確的控件。以下是在開(kāi)發(fā)“”命名空間中的自定義控件時(shí)總結(jié)出來(lái)的原則。(1) 首先要了解頁(yè)事件方法和自定義控件方法之間的調(diào)用順序,具體參見(jiàn)以上陳述。(2) 對(duì)于復(fù)合自定義控件中的子控件,以
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 起重機(jī)設(shè)計(jì)課程設(shè)計(jì)
- 2025年度港口航道疏?;以幚砗贤?篇
- 路面施工課程設(shè)計(jì)
- 該不該學(xué)構(gòu)圖課程設(shè)計(jì)
- 二零二五年度房屋出售合同范本(含房屋交易售后服務(wù)承諾)3篇
- 2025年度校園文化節(jié)贊助商權(quán)益分配合同3篇
- 2025年廣告業(yè)務(wù)員個(gè)人工作計(jì)劃范文(2篇)
- 某加油站油品跑冒漏事故應(yīng)急預(yù)案模版(2篇)
- 二零二五年度文化產(chǎn)業(yè)發(fā)展知識(shí)產(chǎn)權(quán)戰(zhàn)略合作協(xié)議2篇
- 2025年集郵進(jìn)校園活動(dòng)業(yè)務(wù)校長(zhǎng)講話(huà)稿(2篇)
- 飛防合同模板
- 不付租金解除合同通知書(shū)
- NB-T20307-2014核電廠冷卻塔環(huán)境影響評(píng)價(jià)技術(shù)規(guī)范
- 交通事故處理委托書(shū)模板
- 2022-2023學(xué)年浙江省湖州市德清縣人教PEP版四年級(jí)上冊(cè)期末檢測(cè)英語(yǔ)試卷【含答案】
- 2024年九年級(jí)初中數(shù)學(xué)競(jìng)賽輔導(dǎo)講義及習(xí)題解答 第19講 轉(zhuǎn)化靈活的圓中角
- 托福聽(tīng)力課件
- 2023年德宏隴川縣人民法院招聘聘用制書(shū)記員考試真題及答案
- 全球50強(qiáng)藥企官網(wǎng)及LOGO匯總
- 全國(guó)自然教育中長(zhǎng)期發(fā)展規(guī)劃
- 2024年中科院心理咨詢(xún)師官方備考試題庫(kù)-上(單選題匯總)
評(píng)論
0/150
提交評(píng)論