Inside ASP.NET 2.0 – Controls Model(转载)
?
讀者基礎需求:了解ASP.NET 控件設計技巧參考書目:深入剖析ASP.NET 組件設計(碁峯)、
Developing ASP.NET Server Controls And Components(MS Press)
Controls Model 的變革
如你所知曉,ASP.NET 1.x 提供了設計師豐富且易用的控件群,藉由這些控件,設計師可以快速的建構網頁程序,但除了這些表面上看得到的控件外,為了實現組件化設計的理想,ASP.NET 1.x 還提供了簡單但完整的Controls Model ,讓設計師可以自行撰寫控件來增加開發速度,并藉由組件化開發模式來簡化程序的復雜度與降低出錯率。在ASP.NET 2.0 中,這個Controls Model 做了相當大幅度的延伸,除了相容于原來的Controls Model 外,新的Controls Model 還提供了比以往更加豐富的基礎類別。在1.x 時代,老實說控件的開發模式并沒有太嚴謹的規則,設計師只要滿足最基礎的要求,繼承至System.Web.UI.Control 或是System.ComponentModel.Component 就能夠撰寫控件與組件,雖然這給了設計師高度的自由,但也間接的加重組件設計師的工作量,例如撰寫資料感知控件(Data Bound Control)這種很常見的想法,每個設計師硬是得先弄清楚DataSource 與DataField 屬性該如何與IDE Designer 互動,然后再撰寫特定的ControlDesigner 才能完成這樣的控件。為了日后不再重新撰寫這些變動率低、又常用到的程序代碼,有經驗的設計師就會架構自己的一群基礎類別。在2.0,這件事不用勞設計師費心了,ASP.NET Team 已經為常用、可制式化的控件建立一群基礎類別,現在要建立一個資料感知控件,設計師只要繼承至DataBoundControl 即可,不需撰寫ControlDesigner 了,要建立復合式控件也只要繼承至CompositeControl 就行了,這個設計不但簡化了設計師的工作,同時也為控件設計模式定下一個基本的標準,可以讓初學者更容易上手,讓設計師將時間花費在組件真正的功能上。
Adapter Model
Adapter Model 首次出現于ASP.NET Mobile Controls 中,當時主要的設計概念是為了讓ASP.NET 網頁能夠適用于不同的行動裝置,圖1 是該設計的概念。圖1 Mobile Controls
?
Adapter Model 采取Adapter 設計模式,將原本應該由Control 負責的Rending 動作交給另一個對象,也就是ControlAdapter 來完成,當要求到達服務器端時,ASP.NET 會判斷客戶端的裝置類別,建立對應的ControlAdapter 來繪制控件,當然!在為了達到Rending 的動作前提下,除了真正的Rending 動作外,ControlAdapter 與Control 還建立了其它的通道,例如不同的Rending 動作需要有不同的Initialize 動作,也可能需要不同的Pre-Rending 動作,因此ControlAdapter 中定義了一群與Control 幾乎相同的函式,如Init、PreRender、Render 等等。在ASP.NET 2.0 中,Adapter Model 已經被整合入Control 類別中,現在設計師可以為所有的控件建立ControlAdapter,不再僅限于Mobile Control。這個設計的目的分成遠景與近需,近的是為了解決不同瀏覽器需要使用不同的HTML&JavaScript來繪制控件,遠的是為了讓Mobile與PC共享一個網頁,當然!實務上這是很難達到的。
Base Control Classes
那到底有多少基礎類別供我們應用呢?圖2 列出目前筆者所觀察到的類別。圖2 ASP.NET 2.0 的控件基礎類別Control 與WebControl 都是組件設計師熟悉的類別,接下來的DataSourceControl 是ASP.NET 2.0 新引入的Data-Binding 技術所用的基礎類別,在2.0 中,DataSet 已經被SqlDataSource、AccessDataSource、OracleDataSource 等DataSource Control 所取代,而她們的基礎類別就是DataSourceControl。BaseDataBoundControl 就是先前所提及的資料感知控件的基礎類別,她提供了預定義的DataSourceID 屬性,并為設計師預先建構了專屬的ControlDesigner,因此只要繼承至此類別,設計師只需專心撰寫控件的程序代碼,不須再耗費時間處理IDE 的相關細節。DataBoundControl 是更具體化些的基礎類別,除了原有的DataSourceID 之外,另外還提供了DataMember 屬性,她應該是最常用的資料感知控件基礎類別,其子嗣CompositeDataBoundControl 則是用于復合式資料感知組件,如DetailsView、FormView及GridView的基礎類別都是源自于此,HierarchicalDataBoundControl 是另一個支線,她是TreeView、Menu 的基礎類別。最后一個基礎類別是CompositeControl,用于撰寫簡單、不含資料感知能力的復合式控件。
Base Control Designer Classes
基礎類別除了提供一致的實作標準外,更好的是她們預先配備了標準的ControlDesigner 來處理IDE 細節,圖3 是這些基礎類別所配備的基礎ControlDesigner 。。圖3 ASP.NET 2.0 的控件基礎ControlDesigner 讀者們應該可以由名稱來對應出那個基礎類別所用的ControlDesigner。
?
Designer Actions
初用VWD 或VS.NET 2005 的設計師應該都對其新的設計接口感到方便或是累贅,不管是那種感覺,至少新的設計模式真的讓我們減少在WebForm 與屬性盤上來回的次數, 如4 是這個新花招的截圖。圖4 ASP.NET 2.0 的新界面
?
Microsoft 將此技術稱為Smart Task(Smart Tag 之毒?),簡單的說就是將常用的屬性與工作放到這個容器中,讓設計者可以方便的設定她們,不須在屬性表及WebForm 上來來去去,當然!這也有缺點,這個窗口顯示的速度考驗著開發者的計算機速度,何時該縮、何時該展開也考驗著接口設計人員的智能。那如何讓自己的控件擁有這種效果呢?說來也簡單,見程序1。 程序1 建立含有Smart Task 的控件
?
#region?Using?directives?using?System;?
using?System.Collections.Generic;?
using?System.Text;?
using?System.Web.UI.WebControls;?
using?System.ComponentModel;?
using?System.ComponentModel.Design;?
using?System.Web.UI.Design;?
using?System.Web.UI.Design.WebControls;
#endregion?
namespace?ClassLibrary1{?
public?class?SCCDesignerActionList?:?DesignerActionList?{
????private?ControlDesigner?_designer;
????????public?bool?ShowText?{
?????????get?{?return?((SimpleDesignerTest)_designer.Component).ShowText;?}
?????????set?{?((SimpleDesignerTest)_designer.Component).ShowText?=?value;?_designer.UpdateDesignTimeHtml();}
????????}?
????????public?SCCDesignerActionList(ControlDesigner?designer):base()?{
?????????_designer?=?designer;
?????????}
????????public?void?FireShowText()?{
?????????ShowText?=?true;?
????????}
????????public?void?FireHideText()?{
?????????ShowText?=?false;
?????????}?
????????public?override?DesignerActionItem[]?GetSortedActionItems()?{?
?????????DesignerActionPropertyItem?item?=?new?DesignerActionPropertyItem("ShowText",?"Show?Text","Appearence");?
?????????DesignerActionMethodItem?m_item;?
?????????if?(!ShowText)?
??????????m_item?=?new?DesignerActionMethodItem(this,?"FireShowText",?"Show?Text","Actions");?
?????????else
??????????m_item?=?new?DesignerActionMethodItem(this,?"FireHideText",?"Hide?Text",?"Actions");?
?????????return?new?DesignerActionItem[]?{item,m_item};?
????????}
????}
????
????public?class?SCCControlDesigner?:?System.Web.UI.Design.ControlDesigner?{?
????public?SCCControlDesigner()?:?base()?{?}?
????public?override?DesignerActionListCollection?ActionLists?{?
????????get
????????{
?????????DesignerActionListCollection?actions?=?new?DesignerActionListCollection();?
?????????actions.AddRange(base.ActionLists);?
?????????actions.Add(new?SCCDesignerActionList(this));?
?????????return?actions;?
????????}
????
????}?
}?
[DesignerAttribute(typeof(SCCControlDesigner),?typeof(IDesigner))]
public?class?SimpleDesignerTest:WebControl?{
????public?bool?ShowText?{?
????????get?{?
?????????object?o?=?ViewState["ShowText"];if?(o?!=?null)?
?????????return?(bool)o;?
?????????return?true;
????????}
????????set?{ViewState["ShowText"]?=?value;?}
????}
????protected?override?void?Render(System.Web.UI.HtmlTextWriter?writer)?{?
????????if(ShowText)?
?????????writer.WriteLine("TEST");?}
?????????public?SimpleDesignerTest()?{?}?
????????}
}??
?
DesignerActionPropertyItem 指的是一個屬性型態的Smart Tas k,IDE 會將指定的屬性顯示成Smart Task,并套用該屬性所有的屬性編輯器。DesignerActionMethodItem 指的是一
個選項,供使用者點選后執行某些動作,與以前的DesignerVerbs 功能相同。
New Data Binding System
對于ASP.NET 的使用者而言,新的Data Binding 系統無疑是2.0 中變動最大、影響也最深的設計,原來的DataSet 已經被DataSource Control 所取代,這個變動將ASP.NET 的RAD 設計模式推進一大步,DataSource 模式講求將資料操作完全封裝在DataSource Control 中,控件與其的連結僅止與資料的交換,設計師也不再需要煩惱分頁、快取等瑣碎的問題,甚至可以使用ObjectDataSource 來建構分布式系統。對于組件設計師來說, 新的Data Binding 模式影響不大,因為2.0 已經建構了完整的基礎類別,程序2 是一個簡單的Table 控件(因為Beta 1 將DataBoundControlDesigner 標示為抽象類別,因此我們得繼承她才能使用)。
程序2 SimpleTable 控件
?
#region?Using?directivesusing?System;
using?System.Collections;?
using?System.Collections.Generic;
using?System.Text;?
using?System.Web;?
using?System.Web.UI;?
using?System.Web.UI.WebControls;?
using?System.Web.UI.HtmlControls;
using?System.ComponentModel;?
using?System.Web.UI.Design.WebControls;?
#endregion?
namespace?ClassLibrary1?{?
public?class?SimpleTableDesigner?:?DataBoundControlDesigner?{?}?
[Designer(typeof(SimpleTableDesigner))]
public?class?SimpleTable:DataBoundControl?{
private?IEnumerable?_dataRecs;?
protected?override?HtmlTextWriterTag?TagKey?{? get?{?return?HtmlTextWriterTag.Table;?}? }
protected?virtual?void?RenderHeader()?{?
if?(_dataRecs?!=?null)?{?
foreach?(object?item?in?_dataRecs)? {? HtmlTableRow?row?=?new?HtmlTableRow();? foreach?(PropertyDescriptor?prop?in?TypeDescriptor.GetProperties(item))?
{? HtmlTableCell?col?=?new?HtmlTableCell();? col.Controls.Add(new?LiteralControl(prop.Name));? row.Controls.Add(col);
}
Controls.Add(row);
break;?
}
}
}?
protected?virtual?void?RenderRows()
????{?if?(_dataRecs?!=?null)
????{?
????foreach?(object?item?in?_dataRecs)
????????{?HtmlTableRow?row?=?new?HtmlTableRow();?
????foreach?(PropertyDescriptor?prop?in?TypeDescriptor.GetProperties(item))?
????????{?HtmlTableCell?col?=?new?HtmlTableCell();?
????object?v?=?prop.GetValue(item);
????if?(v?!=?null)?col.Controls.Add(new?LiteralControl(v.ToString()));
????row.Controls.Add(col);?}?
????Controls.Add(row);?}?}
}?
private?void?OnSelectCallBack(IEnumerable?data)?{?
????_dataRecs?=?data;
}?
protected?void?RetrieveData()?{
????DataSourceView?view?=?GetData();?
????if(view?!=?null)?
????????view.Select(DataSourceSelectArguments.Empty,?new?DataSourceViewSelectCallback(OnSelectCallBack));?
}?
public?override?void?DataBind()?{?
????ClearChildControlState();?Controls.Clear();
????RetrieveData();
????RenderHeader();
????RenderRows();
????ChildControlsCreated?=?true;?
????TrackViewState();
}?
protected?override?void?OnPreRender(EventArgs?e)?{?
????if?(_dataRecs?==?null)?
DataBind();?
base.OnPreRender(e);?
}?
public?SimpleTable()?{?}
}?}?
?
Non Visual Controls
ASP.NET 2.0 取消了Component Tray ,這代表著Component 在ASP.NET 2.0 中將完全失去RAD 能力,取而代之的是類似DataSource Control 類的非可視型組件,就實務上來說,Non Visual Control 還是一個控件,差別在于IDE 如何看待她,要將某個控件標示為Non Visual Control ,只要配上NonVisualControl Attribute 即可。
?
[NonVisualControl(true)]??
截至目前為止,我仍未發現該Attribute 會對IDE 造成何種影響,或許日后正式版時該Attribute 會用于另一種設計,讓Non Visual Control 不會影響到設計版面。
Web Parts
2.0 將原本于SharePoint 上的Web Parts 整合進來,許多初次接觸Web Parts 的朋友反應都很正面,這個技術可以讓我們與組件化設計模式更貼近,在組件設計上,撰寫一個自訂的Web Parts 也很容易,程序3 是個簡單的范例,她也同時展示了如何使用Web Parts 的Connection 技術。程序3
?
#region?Using?directives??using?System;??
using?System.Collections.Generic;??
using?System.Text;??
using?System.Security.Permissions;?
using?System.Web.UI;??
using?System.Web.UI.WebControls;??
using?System.Web.UI.WebControls.WebParts;??
using?System.ComponentModel;??
#endregion?
?
namespace?ClassLibrary1{??
public?class?MySimpleWebPart:WebPart
?{??
public?override?bool?AllowEdit
?{??
get?{?return?true;?} set?{base.AllowEdit?=?value;?}
}?
public?string?Text?{?get?{?object?o?=?ViewState["Text"];? if?(o?!=?null)?return?(string)o;? return?String.Empty;?}? set?{?ViewState["Text"]?=?value;?}
}
[WebBrowsable,Personalizable(PersonalizationScope.User)]?
public?string?TestVeriable?{?get?{?return?"TEST";?}? set?{?;}
}
[WebBrowsable,Personalizable,Category("Behavior")]?
public?string?TestVeriable2?{?get?{?return?"TEST";?}? set?{?;}
}
[ConnectionProvider("provider","provider")]?
public?object?GetData()?{? return?Text;?
}
[ConnectionConsumer("consumer","consumer")]? public?void?SetData(object?data)?{
Text?=?(string)data;?
}?
protected?override?void?RenderContents(HtmlTextWriter?writer)?{
writer.WriteLine(Text);
}?
public?MySimpleWebPart()?{?}
}? }?
?
Client Callback
ASP.NET 的PostBack 技術使網頁程序的功能更貼近窗口程序,但仍然無法避免于PostBack 發生時畫面的閃爍情況,其實這個問題一直都困擾著許多的設計師,為了讓網頁能在最小閃爍情況下更新,XMLHTTP 技術就應運而生,此技術運用了XML 與HTTP協議,再整合JavaScript 讓網頁可以在某個事件發生時更新一部份的網頁,由于并非是重新向Web Server 要求網頁,因此畫面的閃爍情況可以減到最輕。2.0 整合了此技術,提供了一個標準的JavaScript 及ICallbackEventHandler 接口,控件只要實作此接口,并搭配上適當的JavaScript ,就能達到網頁部份刷新的效果,程序10是一個簡單的范例,LowcaseTextBox會將所有輸入的字串轉成小寫,讀者可以放上她及幾個RadioButton或是CheckBox,當焦點由LowcaseTextBox 離開時,就可發現字串都被轉成小寫,你也會發現,瀏覽器并未重新刷新網頁,也沒有閃爍的情況。程序10 LowcaseTextBox
?
#region?Using?directives?using?System;?
using?System.Collections.Generic;?
using?System.Text;?
using?System.ComponentModel;?
using?System.Web.UI;?
using?System.Web.UI.WebControls;?
#endregion?
namespace?ClassLibrary1{?
public?class?LowcaseTextBox:TextBox,ICallbackEventHandler?{?
private?const?string?SCRIPT?=?
"<script?language='JavaScript'>/n"+?
"function?SetText(eventarg){/n"+?
"document.getElementById('%ID%').value?=?eventarg;/n"+?
"}</script>";?
public?LowcaseTextBox()?{?}
protected?override?void?AddAttributesToRender(?
HtmlTextWriter?writer)?{?
base.AddAttributesToRender(writer);?
writer.AddAttribute(?
HtmlTextWriterAttribute.Onchange,?Page.GetCallbackEventReference(?
this,ClientID+".value","SetText",null));?}?
protected?override?void?OnPreRender(EventArgs?e)?{?
base.OnPreRender(e);?
Page.ClientScript.RegisterClientScriptBlock(?GetType(),?ClientID,?
SCRIPT.Replace("%ID%",ClientID));?
}?
#region?ICallbackEventHandler?Members?
public?string?RaiseCallbackEvent(string?eventArgument)?{?
return?eventArgument.ToLower();?}
#endregion
}?}?
?
Still Running
ASP.NET 2.0 仍在開發中,可以預期的是Web Parts 部份會持續的加強,許多更方便的基礎類別也會一一的加入,相信在2.0 推出后,在控件市場上一定會出現相當多且方便的控件。
?
轉載于:https://www.cnblogs.com/chenying99/archive/2011/10/05/2199226.html
總結
以上是生活随笔為你收集整理的Inside ASP.NET 2.0 – Controls Model(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转)电脑程序员才能看懂的笑话
- 下一篇: 通告,消息,提醒 DB