ASP.NET復合控件的呈現(xiàn)引擎
復合控件是適合用于構(gòu)建復雜組件的工具,在復合控件中,多個子控件聚合到一起,并在彼此之間以及與外部之間進行交互。呈現(xiàn)控件則只用于只讀式控件聚合,其輸出不包括交互元素(例如下拉框或文本框)。
如果您對事件處理和回發(fā)數(shù)據(jù)感興趣,我強烈建議您選擇復合控件。如果使用子控件,則生成復雜的控件樹會更加輕松,而且最終結(jié)果也更清晰簡潔。此外,只有需要提供附加功能時才需要處理回發(fā)接口。
呈現(xiàn)控件不但需要實現(xiàn)附加接口,還要將含有屬性值的標記靜態(tài)部分縫合到一起。
復合控件的優(yōu)點還表現(xiàn)在可以呈現(xiàn)多個同類項,這與在 DataGrid 控件中的情況類似。將每個構(gòu)成項作為活動對象啟用使您可以引發(fā)創(chuàng)建事件并以編程方式訪問它們的屬性。在 ASP.NET 2.0 中,對于要完全實現(xiàn)實際的數(shù)據(jù)綁定復合控件(上述控件只是隨便的舉例)所需的樣板代碼,絕大部分都隱藏在新基類的折疊部分中:CompositeDataBoundControl。
ASP.NET復合控件的呈現(xiàn)引擎
在深入探討 ASP.NET 2.0 編碼技術(shù)之前,讓我們回顧一下復合控件的內(nèi)部例行過程。我們提到過,復合控件的呈現(xiàn)是集中圍繞 CreateChildControls 方法進行的,該方法從 Control 基類繼承而來。您可能會認為,要使服務器控件呈現(xiàn)其內(nèi)容,替換 Render 方法是必不可少的一步。正如我們先前所看到的,如果 CreateChildControls 被替換,則并不總是需要執(zhí)行這一步。但是,何時在控件調(diào)用棧中調(diào)用 CreateChildControls 呢?
如圖中所示,在頁面***次顯示時,會在預呈現(xiàn)階段調(diào)用 CreateChildControls。
ASP.NET復合控件:在預呈現(xiàn)階段調(diào)用 CreateChildControls
特別是,請求處理代碼(在 Page 類中)在將 PreRender 事件引發(fā)至頁面和每個子控件之前會直接調(diào)用 EnsureChildControls。換言之,如果控件樹還未完全生成,則不會呈現(xiàn)任何控件。
以下代碼段例示了 EnsureChildControls(在 Control 基礎(chǔ)上定義的另一種方法)的偽代碼。
- protected virtual void EnsureChildControls()
- {
- if (!ChildControlsCreated)
- {
- try {
- CreateChildControls();
- }
- finally {
- ChildControlsCreated = true;
- }
- }
- }
此方法可能會在頁面和控件的生命周期內(nèi)反復調(diào)用。為避免控件重復,ChildControlsCreated 屬性被設(shè)為 true。如果此屬性返回 true,則該方法會立即退出。
當頁面回發(fā)時,ChildControlsCreated 會在周期前期調(diào)用。如圖 4 所示,它在已發(fā)布數(shù)據(jù)處理階段調(diào)用。
ASP.NET復合控件:發(fā)生回發(fā)時在已發(fā)布數(shù)據(jù)處理階段調(diào)用
當 ASP.NET 頁面開始處理從客戶端發(fā)布的數(shù)據(jù)時,它會嘗試查找一個其 ID 與已發(fā)布字段的名稱相匹配的服務器控件。在執(zhí)行此步驟期間,頁面代碼會調(diào)用 Control 類中的 FindControl 方法。反之,該方法需要確保在進行操作之前控件樹已完全生成,因此它調(diào)用 EnsureChildControls 并按需要生成控件層次結(jié)構(gòu)。
那么要在 CreateChildControls 方法內(nèi)部執(zhí)行的代碼是怎樣的呢?盡管沒有正式的指南可供遵循,但通常認為 CreateChildControls 至少必須完成以下任務:清除 Controls 集合,生成控件樹,并清除子控件的視圖狀態(tài)。并不嚴格要求必須從 CreateChildControls 方法內(nèi)部設(shè)置 ChildControlsCreated 屬性。實際上,ASP.NET 頁面框架始終通過 EnsureChildControls(此方法可自動設(shè)置布爾標記)來調(diào)用 CreateChildControls。
【編輯推薦】