|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
前天傍晚我发表了《Java的跨平台就是一句谎言。》,原本就是周末闲来无事,发表一篇略带争议性的博文让大家都来吵吵架,发表自己的看法,根本就没想着谁把谁打倒,一个行业或者是技术阵营是无法用短期口水仗打到对手的。asp.net|服务器|控件 在上一篇文章中,我们会商了有关视图形态的内容。部分读者已发明,假如页面大概控件禁用了视图形态,那末开辟职员将没法包管使用ViewState存储的形态信息得以一般使用。这关于ViewState而言,切实其实是一个缺点。为懂得决这个成绩,ASP.NET2.0新增了一个手艺特征--控件形态。本文起首对控件形态的基础观点举行先容,然后经由过程一个典范示例,申明控件形态使用办法。必要提示读者的是,在浏览本文,了解控件形态的之前,倡议起首浏览上一篇文章中视图形态的观点。
控件形态概述
为了让服务器控件一般事情,偶然必要存储控件形态数据。比方,假如编写了一个自界说控件,个中具有显现分歧信息的分歧选项卡,为使该控件如预期一样事情,控件必要晓得在往复过程当中选择的是哪一个选项卡。ViewState可用于此目标,可是,开辟职员大概在页级别封闭了视图形态,从而无效地中止控件。为办理此成绩,ASP.NET2.0增添了一种称为"控件形态"的新功效。
整体而言,控件形态与视图形态有着良多相似的地方,比方,两者都能够用于完成形态信息存储和办理,其相干数据都存储在一个或多个埋没字段中等等。但是,控件形态的最年夜特性是:控件形态不克不及被封闭,这一点与视图形态完整分歧,同时,该手艺特征仅为服务器控件局限利用,不克不及用于Web页面局限。当页面大概某个控件禁用了视图形态功效时(EnableViewState="false"),控件形态仍可照旧利用,涓滴不受影响。而此时与视图形态有关的功效则会遭到影响,没法事情了。因而可知,控件形态关于进步控件牢靠性、天真性等方面有侧重要意义。
与视图形态不异,在控件形态中一样撑持存储多多种数据范例工具,而且其默许撑持的范例局限加倍普遍。详细包含的数据范例有:Array、DateTime、Int16、String、ArrayList、Double、Int32、String[]、Boolean、Enum、null(Nothing)、System.String.Empty、Byte、Hashtable、Pair、Triplet、Char、HybridDictionary、Single、Type、Color、IDictionary。
使用控件形态的办法对照复杂,其包含两个关头历程:
(1)在初始化过程当中(OnInit事务处置办法)挪用RegisterRequiresControlState办法;
(2)重写SaveControlState和LoadControlState办法。个中前者用于启用并唆使服务器控件利用控件形态,后者用于保护控件形态数据。
上面经由过程一个复杂的示例申明控件形态的使用办法。详细代码以下所示:
publicclassSample:Control{
privateintcurrentIndex=0;
//重写OnInit事务处置程序
protectedoverridevoidOnInit(EventArgse){
Page.RegisterRequiresControlState(this);
base.OnInit(e);
}//重写SaveControlState办法
protectedoverrideobjectSaveControlState(){
returncurrentIndex!=0?(object)currentIndex:null;
}//重写LoadControlState办法
protectedoverridevoidLoadControlState(objectstate){
if(state!=null){currentIndex=(int)state;}
}
}
如上代码所示,自界说服务器控件Sample承继自Control,其重写了三个主要办法:OnInit、SaveControlState和LoadControlState。
在重写OnInit办法过程当中,起首挪用Page类的RegisterRequiresControlState办法,以唆使自界说控件利用控件形态,然后再挪用基类办法。SaveControlState办法用于保留自页回发到服务器后产生的任何服务器控件形态变动,个中参数state暗示要复原的控件形态的Object。如代码所示,重写该办法次要完成了断定外部属性currentIndex是不是设置为非默许值,假如是,则将值保留到控件形态。LoadControlState办法用于从SaveControlState办法保留的上一个页哀求复原控件形态信息。如代码所示,重写该办法次要完成了断定之前是不是为控件保留过控件形态,假如保留过,则将外部属性currentIndex设置为保留的值。
读者必要注重的是SaveControlState和LoadControlState办法。这是ASP.NET2.0为Control类新增的成员办法。开辟职员可经由过程重写这两个关头办法,以便完成对自界说服务器控件控件形态数据的办理和把持。在服务器控件实行过程当中,SaveControlState办法在完成保留自界说视图形态数据的办法SaveViewState之前激发,LoadControlState办法在完成加载自界说视图形态数据的办法LoadViewState之前激发。
利用控件形态具有以下几个长处:
1、泯灭的服务器资本较少(与Application、Session比拟)。默许情形下,控件形态存储在页上的埋没域中。
2、具有壮大的牢靠性。由于控件形态不像视图形态那样能够封闭,控件形态是办理控件形态信息的更牢靠办法。
3、具有必定天真性。开辟职员能够编写程序来把持怎样存储控件形态数据和控件形态数据的存储地位。
利用控件形态的次要弱点是必要一些编程。固然ASP.NET页框架为控件形态供应了基本,可是控件形态是一个自界说的形态坚持机制。为了充实使用控件形态,开辟职员必需编写代码来保留和加载控件形态。
<P> 典范使用
前文已较为具体的先容了控件形态的基础观点。本大节将经由过程一个示例申明控件形态的使用办法,以便加深读者关于基础观点的熟悉。
示例枚举了一个同时在控件形态和视图形态中保留形态的自界说控件IndexButton。在此示例中,IndexButton控件派生自Button类,还界说了一个IndexControlState属性,并将该属性值保留在控件形态中。为了举行对照,IndexButton还界说了一个IndexInViewState属性,该属性存储在ViewState字典中。控件完成详细源代码以下所示:
usingSystem;
usingSystem.ComponentModel;
usingSystem.Security.Permissions;
usingSystem.Web;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
namespaceWebControlLibrary{
[AspNetHostingPermission(SecurityAction.Demand,Level=AspNetHostingPermissionLevel.Minimal),AspNetHostingPermission(SecurityAction.InheritanceDemand,Level=AspNetHostingPermissionLevel.Minimal),ToolboxData("<{0}:IndexButtonrunat="server"></{0}:IndexButton>")]
publicclassIndexButton:Button{
//界说公有变量
privateint_indexInControlState;//使用控件形态完成属性
IndexInControlState[Bindable(true),Category("Behavior"),DefaultValue(0),Description("该属性利用控件形态存储.")]
publicintIndexInControlState{
get{return_indexInControlState;}
set{_indexInControlState=value;}
}//使用视图形态完成属性
IndexInViewState[Bindable(true),Category("Behavior"),DefaultValue(0),Description("该属性利用视图形态存储.")]
publicintIndexInViewState{
get{
objectobj=ViewState["IndexInViewState"];
return(obj==null)?0:(int)obj;
}
set{
ViewState["IndexInViewState"]=value;
}
}
//重写OnInit办法,启用页面控件形态
protectedoverridevoidOnInit(EventArgse){
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
//重写SaveControlState办法,保留控件形态数据
protectedoverrideobjectSaveControlState(){
objectobj=base.SaveControlState();
if(_indexInControlState!=0){
if(obj!=null){
returnnewPair(obj,_indexInControlState);
}else{
return(_indexInControlState);}
}else{returnobj;}
}
//重写LoadControlState办法,加载控件形态数据
protectedoverridevoidLoadControlState(objectstate){
if(state!=null){
Pairp=stateasPair;
if(p!=null){
base.LoadControlState(p.First);
_indexInControlState=(int)p.Second;
}else{
if(stateisint){
_indexInControlState=(int)state;
}else{base.LoadControlState(state);}
}
}
}
}
}
如上代码完成了一个承继自Button基类的IndexButton控件,个中包含属性IndexControlState和IndexInViewState。依据代码完成可知,IndexInViewState属性使用了视图形态来存储值,而Index属性使用了控件形态来存储值。前者的完成十分复杂,在此不再申明。后者的完成次要经由过程完成以下三个步骤,才使控件介入控件形态。
(1)重写OnInit办法并挪用RegisterRequiresControlState办法向页面注册,以介入控件形态。必要注重的是:必需针对每一个哀求完成此义务。
(2)重写SaveControlState办法,以在控件形态中保留数据。
(3)重写LoadControlState办法,以从控件形态加载数据。此办法挪用基类办法,并猎取基类对控件形态的基值。假如_indexInControlState字段不为零,并且基类的控件形态也不为空,Pair类即可作为便利的数据布局利用,用来保留和复原由两部分构成的控件形态。
读者能够回忆一下前一篇先容视图形态文章中的示例。个中一样也界说了两个属性,一个是接纳视图形态构建的TextInViewState属性,另外一个是利用公有变量完成的Text属性。前者TextInViewState属性与上文示例中的IndexInViewState属性的完成办法几近完整不异,其不过是使用ViewState存储属性值罢了。但是,后者Text属性与上文示例的IndexInControlState属性固然有些相似,比方,两者在完成过程当中都利用了公有变量,可是,两者的实质分歧。Text利用的是公有变量,而IndexInControlState利用的是控件形态,其关头是经由过程OnInit办法启用了控件形态功效,偏重写SaveControlState和LoadControlState办法,以便自界说控件形态数据的保留和加载历程。倡议读者在浏览本文的同时,也可以注重到本段所述内容。这关于了解视图形态和控件形态观点有侧重要意义。
上面枚举了为测试IndexButton控件而创立的Default.aspx页面源代码。
<%@PageLanguage="C#"EnableViewState="false"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default"%>
<%@RegisterAssembly="WebControlLibrary"Namespace="WebControlLibrary"TagPrefix="aspSample"%>
<scriptrunat="server">
voidPage_Load(objectsender,EventArgse){
Label1.Text=(IndexButton1.IndexControlState++).ToString();
Label2.Text=(IndexButton1.IndexInViewState++).ToString();
}
</script>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title>利用视图形态和控件形态</title>
</head>
<body>
<formid="form1"runat="server">
<div>请单击该按钮:<aspSample:IndexButtonText="IndexButton"ID="IndexButton1"runat="server"/>
<br/><br/>
Index属性值是:<asp:LabelID="Label1"runat="server"Text="Label"></asp:Label>
<br/>IndexInViewState属性值是:<asp:LabelID="Label2"runat="server"Text="Label"></asp:Label>
<br/>
</div>
</form>
</body>
</html>
以上代码很复杂。关头是读者要注重在@Page指令中设置了EnableViewState="false",以便在页面禁用视图形态。此时,页面及页面内的一切控件,包含IndexButton都没法利用视图形态。那末,当运转该页面时应出现如何的使用效果呢?详细页面使用效果如所示。
如所示,当用户单击"IndexButton"按钮时,因为页面禁用了视图形态,因而,IndexInViewState属性没法完成实在际功效,其属性值将一向坚持为0。但是,页面禁用视图形态关于由控件形态完成的属性IndexControlState而言,则没有涓滴影响。每当用户单击按钮一次,那末个该属性值增添1。
经由过程以上示例,信任读者已对视图形态和控件形态有了更加深切的熟悉。但是,大概仍是有一个疑问环绕纠缠在心中:视图形态和控件形态云云类似,那末该在何种情形下利用视图形态,又在何种情形下利用控件形态呢?一般而言,视图形态当必要存储大批回发到本身的页信息时利用。利用ViewState属性可供应具有基础平安性的功效。控件形态当必要在服务器的往复历程间存储大批控件形态信息时利用。关头的一点是:应当对那些在回发过程当中,对控件相当主要的大批关头数据利用控件形态,而不要将控件形态作为视图形态的备用选项利用。
小结
本文次要先容了控件形态的基础观点,并经由过程一个典范示例申明了这类手艺特征的使用办法。必要再次提示的是:仅对那些在回发过程当中对控件相当主要的大批关头数据利用控件形态,而不要将控件形态作为视图形态的备用选项利用。这是开辟职员使用视图形态和控件形态的关头地点。
我有个同学,他是搞Java的,他给我说“Java不是效率低,而是速度慢。”,我不是搞Java的,我实在想不透这句话的含义,难道执行速度不就是效率低吗?难道执行速度慢还成效率高了? |
|