冷月葬花魂 发表于 2015-1-16 22:48:22

ASP.NET编程:切磋ASP.NET 2.0中的Web控件改善手艺

有专家说:java不是跨平台,java就是平台,这很好的定义了java的特点。有了java,你只需要等待java平台在新平台上移植。这还不错吧!只是,java不是一个平台,而是多个平台。你需要在这个java平台移植到另一个java平台。asp.net|web|控件  ASP.NET2.0并没有丢弃1.1版本中的任何现有控件,而是增添了一组新的控件;同时还引进了多少新的控件开辟手艺。本系列文章将对这些内容睁开周全切磋。
  1、弁言
  到今朝为止,你大概已懂得了大批的ASP.NET2.0新特性―母版页面,主题,供应者,等等……一切如许内容都相称出色;可是,你是不是懂得到有关定制Web控件开辟方面的严重变更?这恰是我在本文中所想会商的。假如你已处置于控件开辟,那末,我想本文所形貌的ASP.NET2.0中的新的改善特性会当即使用于你的控件开辟中。
  起首应当注重的是,你之前利用ASP.NET1.1(或1.0)开辟的一切Web控件在2.0版本下将持续优秀运转―微软并没有损坏你的现有代码。在本文中,我将向你先容的一切相干内容,包含很多新的使人冲动的手艺,一切这些你都能够增加到现有控件或在新的控件情况中利用。
  作者注:本文假定你对定制Web控件开辟已有一个基础懂得。在本文中,我以一个加强版本的EmailContact控件为例对ASP.NET2.0中的Web控件改善手艺作周全切磋。
  2、改善
  表格1形貌了ASP.NET2.0在定制Web控件开辟方面所作的年夜部分的严重改善。在本系列文章中,我将对这些特性睁开一一会商。
  表格1:ASP.NET2.0Web控件改善功效。



  3、加强EmailContactWeb控件
  本文中的定制EmailContactWeb控件(参考)同意在你的站点中到场一个“contactus”表单,它具有完全的电子邮件功效。在本文中,我将利用该功效加强这一控件。



  .缺省形态下的EmailContact控件
  4、一个新的基类
  之前,开辟者都是从WebControl类派生他们的可视化Web控件。我之以是在此利用了“可视化”一词是由于,典范情形上,没有在扫瞄器中天生任何内容的控件都是派生自Control类。这一点并没有改动―你应当持续利用该Control类来派生任何如许的非可视化控件―它们实行不成见功效或在扫瞄器中天生除可视化HTML内容以外的任何别的内容。并且,在开辟可视化Web控件时,你还应当持续利用WebControl类。但是,我们所开辟的年夜多半复合控件都是为了使用现有控件的功效。在这类情形下,你应当老是从WebControl类举行派生,可是你还要记着别的一些有关细节―不然的话,有大概招致很多成绩。
  复合控件必需完成INamingContainer接口,而且必要包含在你的控件类中。这个接口可以确保在你的控件及其能够天生的全部控件条理中的一切的HTML标签中都具有独一的标签定名。当你在单个页面上存在多个不异范例的复合控件的情形下,这是相称关头的。在如许的情形下,你必要确保任何天生的子元素都具有独一的称号。健忘完成该接口可以招致各类成绩的呈现。
  在ASP.NET2.0之前,复合控件开辟者还必要记着在一个控件的Render办法中挪用EnsureChildControls。在我之前的文章中已经向你先容怎样重载该Render办法而且在挪用基类的Render办法前挪用这个办法。要使控件在VisualStudio计划时候准确天生这一步是需要的;不然,有大概带来很多方便。
  下面两个步骤在复合控件开辟中云云广泛,乃至于很多开辟者常常城市构建一个包含这两个细节的基类,然后从该基类下派生他们一切的新的复合控件。作为取代,ASP.NET2.0供应了(更正确地说是“名字为”)CompositeControl。借助于这个类来构建你的复合控件,你就不用再记着完成INamingContainer或从Render办法中实行一个EnsureChildControls挪用了。
  别的,还存在别的一些新的基类,比方用于数据绑定的控件等,在此不再赘述。
  我的概念是:ViewState有大概成为你最好的伴侣,也有大概成为你最坏的仇人―这要依附于你利用它的体例来决意。假如你在之前已经利用过ViewState,那末,你一定会喜好新的ControlState。
  关于ViewState的最使人头痛的成绩之一就是,它的“all-or-nothing”形态办理办法。页面开辟者能够很简单地决意在任何控件级,页面级或在全部站点级(经过web.config)上封闭ViewState。现实上,假如你在全部站点级上经由过程web.config封闭ViewState的话,那末,你无妨推测一下你还可以在别的甚么中央封闭它?谜底是:还能够在machine.config中完成―在此情形下,它可以影响到统一服务器上的一切站点。假如一个页面开辟者决意关失落在ViewState中完成形态办理的才能,那末,你的控件天生有大概呈现部分不成用,或更有甚者―完整不成用。
  为此,在新版本中,微软创立了ControlState―旨在办理这一成绩。页面开辟者不克不及关失落ControlState,因而利用它举行属性选择更加平安。
  利用ControlState与利用ViewState几近完整分歧。但是,ControlState并没有供应象ViewState如许的一个变量,而是供应了称为SaveControlState和LoadControlState的办法以便于你的控件可以举行重载。这些办法与SaveViewState和LoadViewState办法的事情道理完整分歧。
  由于ControlState在属性语句中没有供应一个响应的变量,以是,你必需借助于ASP.NET开辟者之前在他们的工具中所利用的成员变量(属性语句)来完成不异的功效。
<P>  Protected_MailServerAsString="Firstname:"
  PublicPropertyMailServer()AsString
  Get
  Return_MailServer
  EndGet
  Set(ByValvalueAsString)
  _MailServer=value
  EndSet
  EndProperty
  但是,由于我利用了一个尺度的成员变量来保留值,以是我必要一种办法以便把数据存储在ControlState中―这恰是后面提到的办法“退场”的缘故原由。就象在它们响应的ViewState办法中那样,ASP.NET将在页面熟命周期内挪用这两个办法。个中,SaveViewState办法前往一个将被耐久存储的工具范例。经由过程前往一个工具数组,这个办法能够存储多个值。而且,就象产生在SaveViewState办法中一样,也是利用数组的0下标元从来挪用基类的SaveControlState办法。
<P>  ProtectedOverridesFunctionSaveControlState()AsObject
  Dimstate()AsObject=NewObject(2){}
  state(0)=MyBase.SaveControlState()
  state(1)=_MailServer
  Returnstate
  EndFunction
  注重:LoadControlState办法以一个工具作为参数―这个工具是之前在SaveControlState中前往的一个工具。在这个办法中,我从头分派了成员变量―经由过程把该参数转换为一个工具数组,然后取得每一个下标的值。与之前一样,我利用数组的0下标来挪用基类的LoadControlState办法。
<P>  ProtectedOverridesSubLoadControlState(_
  ByValsavedStateAsObject)
  IfsavedStateIsNotNothingThen
  Dimstate()AsObject=CType(savedState,Object())
  MyBase.LoadControlState(state(0))
  _MailServer=CType(state(1),String)
  EndIf
  EndSub
  借助于这些办法来存储数据,在页面开辟者关失落ViewState时,控件就不会呈现后面那些贫苦。
  你大概对ControlState的存储地位感应惊奇;它对应于另外一个天生到HTML页面中的埋没的文本框。就象在ViewState情形下数据被存储在__ViewState埋没文本框中相似,ASP.NET2.0利用__ControlState埋没文本框来存储ControlState数据。
  遗憾的是,微软没有向开辟者供应内涵地利用ControlState的才能―就象在ViewState情形下那样。以是,为了ControlState利用,你必要注册你的控件。你能够重载控件的OnInit事务而且挪用Page工具的RegisterRequiresControlState办法。
<P>  ProtectedOverridesSubOnInit(ByValeAsSystem.EventArgs)
  MyBase.OnInit(e)
  IfPageIsNotNothingThen
  Page.RegisterRequiresControlState(Me)
  EndIf
  EndSub
  如今,你可使用ControlState来存储你以为充足主要的数据―假如不把它存储起来,那末你的控件大概天生一些无用的内容。
  记着,你在计划时候对属性的修正将被硬编码到该控件的ASPX声明中,从而在相邻的再次回寄之间主动地存储。但是,假如表单上的一个举动改动了一个控件的属性,那末,这将会激活形态办理机制的利用。假如不把该属性存储在一个形态中,那末,鄙人一次回寄时它将恢复到“硬编码”形态。
  如今,总的来看,我们应当把与表面相干的属性存储在ViewState中,而把与举动相干的属性存储在ControlState中。经由过程这类体例,假如一个页面开辟者关失落ViewState,那末你的控件只管大概看起来模样别扭,可是仍能准确事情。
  当你最入手下手在VisualStudio2005中利用Windows表单控件或是ASP.NETWeb控件时,你起首会注重到,在很多控件右上角呈现一个箭头外形的小玩艺儿(见中的示例)。点击这个箭头会弹出一个小窗口,个中包括该控件的一些属性,另有一两个链接。微软计划这些敏捷标签是为了显现你必要操纵的一些属性,其终极目标是为了使该控件在一个页面或表单上可以准确事情;而且你将注重到,它们比一个一般的快速菜单更加精巧。本节中我们会商的内容既合用于Windows表单控件也合用于ASP.NET服务器控件。
  


  .EmailContact控件的敏捷标签
  为了构建你本人的敏捷标签,你必要利用一个控件计划器类。现实上,你在别的别的一些成绩上也会利用这个类。可是,在我具体会商计划器类前,我想先创立一个ActionList类―这个类将界说我的敏捷标签中包括的元素。
  一个ActionList类承继自System.ComponentModel.Design定名空间中的DesignerActionList类。可是,在具体会商这个类之前,让我先来注释一下存在于敏捷标签中的四品种型的元素:categoryheader,propertymapping,actionlink和informationitem。展现了我构建这个敏捷标签的方针。你可以从中看出我所指的这四品种型的元素吗?我把这个敏捷标签依据题目分为三类:“Appearance&Behavior”,“Support”和“Information”。个中,“Appearance&Behavior”分类中包括了两个属性:MailServer和Pre-definedDisplay。这些实践上都是EmailContact控件自己的属性。“Support”分类包括两个激活某些范例的一个举动的链接,而“Information”分类仅用于显现信息。如今,有了这四品种型的元素,我将动手创立我的ActionList类。
  我将创立一个称为EmailContactActionList的类,而且从DesignerActionList中加以派生。(你能够在本文源码列表1中看到完全的类)。我将创立一个机关器―它吸收一个EmailContact实例作参数而且把它的局限扩展到一个称为ctlEmailContact的类级变量。前面,当我把代码增加到计划器类时,你将看到这个机关器的利用情形。如今,我已创建了一个类级的工具,它包括我正在计划的Web控件的实例。
  接上去,我将创立敏捷标签将显现的属性的“propertymapping”。在中,你看到我已在该敏捷标签中标出了两个属性:MailServer和PreDefinedDisplay。这些将分离映照到EmailContact控件的称为MailServer和PreDefinedDisplay的属性上。ActionList类中的属性映照将在get存取器中前往控件的属性,而在set存取器中设置控件的属性。但是,因为微软计划ActionList基本布局的体例决意了,你不克不及间接设置该控件的属性。而是,你必需利用反射机制来存取该控件的属性,然后再设置它的值。为了便利这一完成,我编写了一个称为GetControlProperty的办法,它可以前往一个PropertyDescriptor工具。如许以来,开辟者就不必要再反复每种属性映照下的反射编码。上面是一个属性映照看起来的模样。
<P>  PublicPropertyMailServer()AsString
  Get
  ReturnctlEmailContact.MailServer
  EndGet
  Set(ByValvalueAsString)
  GetControlProperty("MailServer")._
  SetValue(ctlEmailContact,value)
  EndSet
  EndProperty
  接上去,我必要创建的是你在中所看到的链接:“AboutEmailContact”和一个到我本人的网站的链接。这些链接将实行我将在这个类中创立的办法。我的第一个办法名为ShowAboutBox,它显现一个Windows表单以用作我的控件的一个“关于”信息提醒窗口。第二个办法称为LaunchWebSite,它实行一个对System.Diagnostics.Process.Start的挪用以便在一个扫瞄器实例中启动我的网站。这两个办法的独一的请求是:每个署名都必需是一个“Sub”(在C#言语中响应于一个void函数)而且不带参数。
  注重,在这个敏捷标签示例中仅显现了两个属性和两个链接,可是借助于我方才所展现的手艺,你完整能够供应你所必要的尽能够多的这些工具。但是,我倡议:不要利用太多的信息来重载一个敏捷标签。记着,你仅想把信息放于此以便页面开辟者当即利用,从而使得Web控件开辟更具直不雅性。
  如今,既然我已创立了我的属性映照和举动办法,那末接上去,我将创立敏捷标签的内容。个中,DesignerActionList类供应一个称为GetSortedActionItems的重载函数。今后,一个计划器类将重载这个函数,而且它会前往一个DesignerActionItemCollection(界说于System.ComponentModel.Design定名空间)范例的工具。
  这个属性重载的完成部分将创立一个新的DesignerActionItemCollection工具而且利用四个分歧的类(DesignerActionHeaderItem,DesignerActionPropertyItem,DesignerActionMethodItem和DesignerActionTextItem)的实例来添补它。注重,这四个类都派生自笼统DesignerActionItem类。上面,我将同你逐一睁开会商。
<P>  Dimo_ItemsAsDesignerActionItemCollection=_
  NewDesignerActionItemCollection
  这段代码利用DesignerActionHeaderItem类来创立敏捷标签分类头部,而且在它们的机关器中吸收分类名字。我将间接把这个类的实例拔出到我方才创立的汇合中。
<P>  o_Items.Add(NewDesignerActionHeaderItem(_
  "Appearance&Behavior"))
  为每种分类创立正确的题目是相称主要的,这不但是由于它作为在敏捷标签中作为该分类的头部响应的显现文本这一用处。早些时分,我创立了两个分离称为MailServer和PreDefinedDisplay的属性映照;如今我想把它们增加到敏捷标签中。为此,我将创立DesignerActionPropertyItem类的实例而且把它们增加到汇合中。
<P>  o_Items.Add(NewDesignerActionPropertyItem(_
  "MailServer","MailServer",_
  "Appearance&Behavior"))
  注重,该机关器吸收三个参数:属性名,将呈现在敏捷标签上的文本信息,和响应范例的正确题目(在DesignerActionHeaderItem的实例中界说)。
  接上去,我想以不异的体例把举动链接增加到敏捷标签。注重,也仅仅是在此时,我们利用了DesignerActionMethodItem类的实例。
<P>  o_Items.Add(NewDesignerActionMethodItem(_
  Me,"ShowAboutBox","AboutEmailContact2",_
  "Support","Displaystheaboutbox.",True))
  在此,机关器吸收办法名,链接申明,范例文本和一个用作链接的提醒信息的形貌等共四个参数。个中,第四个参数决意这个链接是不是还呈现在属性扫瞄器的底部。
  最初,我将把信息项增加到敏捷标签中―这是利用DesignerActionTextItem类来完成的。
<P>  o_Items.Add(NewDesignerActionTextItem(_
  "ID:"&ctlEmailContact.ID,"Information"))
  在此,机关器仅吸收要显现的文本和该文本要安排的范例。
  列表1(见源码文件)中的终极代码展现了我要增加到这个汇合中的一切项。当该办法完成时,它复杂地前往这个汇合。在前面一篇中,我们将会商控件计划器类的成绩。
  1、控件计划器
  控件计划器类派生自System.Web.UI.Design.WebControls.CompositeControlDesigner。该类经由过程控件类中声明的一个属性绑定到控件上:
  DesignerAttribute(GetType(EmailContactDesigner))
  在Web表单计划器中,它可以把控件的一切表面和举动特性出现在用户眼前。当页面开辟者把一个Web控件拖动到Web表单上时,页面开辟者能够经由过程各类交互体例获得控件的各类属性。这些属性将影响到页面开辟者所看到的内容―不但是影响到控件自己,还包含一些更奇妙的幕后元素(比方敏捷标签)。
  实践上,控件计划器可以在计划时候天生一种与运转时候分歧的输入了局。在有些情形下,一个控件在运转时候大概没有任何可视化天生,可是却请求在计划时候完成一些显现,以便更简单地操纵它。这类情形的一个示例就是,ASP.NET2.0中所供应的声明性数据源。这些控件供应了数据存储弛缓冲功效,可是却没有可视化天生。但是,在计划时候,它们体现为一个带有一些形貌性文本的灰色窗口―呈现在web表单计划界面上。另外一个关于分歧天生的例子是,有些控件不天生任何内容―除非它们被绑定到数据源。比方,当GridView(在1.1版本中是DataGrid)带无数据时,它看上往非常一般;但当不存在要显现的数据行时,看上往甚么器材也没有(或只显现为空的头部)。当你把一个如许的控件拖动到Web表单上时,控件常常利用几个具有示例性子的空数据行举行显现―这是由计划器类所供应的。
  当VisualStudio必要决意在一个敏捷标签中显现的内容时,它存取计划器类的一个称为ActionLists的属性,而且利用它的了局来构建该敏捷标签。该ActionLists属性前往一个System.ComponentModel.Design定名空间中的DesignerActionListCollection范例的工具。在我的计划器类中,我将重载这个属性而且构建一个DesignerActionListCollection工具。我将前往的这个工具将在类局限上加以声明,而且反省ActionLists属性是不是是一个“nothing”值。
<P>  Privateo_ActionListsAs_
  DesignerActionListCollection
  控件计划器中的值都是被缓冲的,因而不必要被反复创立,以便使计划器更加无效地天生控件。
  控件计划器类的一个主要特性是一个称为Component的成员。它是在控件计划器类所承继的基类中举行声明的,而且包括一个对实践的控件(计划器类被绑定到其上)的援用。我可使用这个变量,而且把它转换成我的实践的控件范例―既然该变量被声明为object范例。
<P>  DimctlEmailContactAsEmailContact=_
  CType(Component,EmailContact)
  其了局是一个称为ctlEmailContact的工具,它包括一个这个类以后正在计划的实践控件的强范例实例。以是,我在这个工具上作的任何改动或实行的任何操纵都将当即被反应到Web表单计划界面中,并出现在页面开辟者眼前。
  关于这个属性重载的别的方面的完成还包含,把我后面创立的ActionList类的一个实例增加到我在类级上创立的DesignerActionListCollection工具。
  o_ActionLists.Add(NewEmailContactActionList(ctlEmailContact))
  你大概还记得我在EmailContactActionList类中创立的一个机关器,事先它吸收EmailContact控件的一个实例。如你所见,我在此也利用了该机关器―把我计划的控件实例传送给它。
  上面是控件计划器类用于构建敏捷标签的完全源码:
<P>  Privateo_ActionListsAsDesignerActionListCollection
  PublicOverridesReadOnlyPropertyActionLists()As_
  System.ComponentModel.Design.DesignerActionListCollection
  Get
  Ifo_ActionListsIsNothingThen
  o_ActionLists=NewDesignerActionListCollection
  DimctlEmailContactAsEmailContact2=_
  CType(Component,EmailContact2)
  o_ActionLists.Add(_
  NewEmailContactActionList(ctlEmailContact))
  EndIf
  Returno_ActionLists
  EndGet
  EndProperty
  在这个示例中,我仅创立了一个ActionList类,利用举动列表项添补它,而且把该类增加到将被前往的DesignerActionListCollection类―这是经由过程重载控件计划器的ActionLists属性来完成的。实在,我完整能够据实践必要创立很多ActionList类,而且复杂地把它们增加到ActionLists属性汇合便可。假如我想在逻辑上构造大批的敏捷标签项―为了在多个控件中重用它们时,这是很有效的。至于决意为什么和什么时候如许做,则要依附于实践来决意。
  如今,在我编译完这个控件并把它拖动到一个表单上时,我将看到一个小箭头呈现在其右上角―点击它将显现你在中所看到的内容。在此,改动任何个中一个属性都与在属性扫瞄器中改动完整分歧。点击响应的链接将实行在EmailContactActionList类的办法中界说的举动。
  关于该控件,我们就会商这些内容。记着一点:不要把临时不必要的属性增加到一个敏捷标签中。
  2、模板计划时候编纂
  在之前的文章中,我已经先容过怎样在你的控件中增加模板才能。在此,我仅复杂地触及个中一点,由于它与这里的会商有一些干系―我指的是从Web表单计划界面上编纂模板内容的才能―在之前的ASP.NET1.x时期这是不简单完成的。
  模板计划时候编纂功效呈现在比方GridView如许的控件中―你能够把该控件置于“模板编纂”形式,然后只需把别的控件拖动到该模板地区便可。假如没有这类便利的话,页面开辟者必需切换到ASPX视图并象上面如许手工地创立模板内容:
<P><dnd:EmailContactID="ctl1"runat="server">
<HeaderTemplate>
<asp:LabelID="lbl1"runat="server"Text="Label"/>
<asp:TextboxID="txt1"runat="server"/>
</HeaderTemplate>
<FooterTemplate>
<asp:LinkButtonID="lnk1"runat="server"Text="LinkButton"/>
</asp:LinkButton>
<asp:DropdownListID="ddl1"runat="server"/>
</FooterTemplate>
</dnd:EmailContact>
  只管这也并非太糟,可是使页面开辟者利用计划器界面举行计划效果会更好一些。
  为了把模板编纂才能增加到一个控件上,你必需重载控件计划器类的Initialize办法,而且设置一个标记以关照计划器你想撑持模板编纂功效。
<P>  PublicOverridesSubInitialize(_
  ByValComponentAsIComponent)
  MyBase.Initialize(Component)
  SetViewFlags(ViewFlags.TemplateEditing,True)
  EndSub
  注重在此,我对基类办法举行了挪用以确保我不作废本人不想完成的内容。这个挪用关照计划器它将撑持模板编纂功效,可是你仍旧必要对编纂完成部分举行编程。
  微软所利用的构建立计器的体例是,把模板分类到模板组中;这类情形下,在你的控件中将会存在很多模板。模板自己是在一个称为TemplateDefinition的工具中界说的;而TemplateGroup工具包括一个或多个这些界说工具。TemplateGroup工具包括在一个TemplateGroupCollection范例的工具中;因而,恰是在这里(TemplateGroupCollection范例的工具中),计划器类将在类级上声明一个这类范例的变量。就象在敏捷标签情形下一样,基本布局卖力缓存这个工具―这恰是我在一个类级局限上声明它的缘故原由。
  Privateo_TemplateGroupsAs
  TemplateGroupCollection=Nothing
  这个汇合获得一个称为TemplateGroups的内置属性―我如今必需重载之。恰是这个属性的内容将被表露给页面开辟者以完成响应的模板编纂功效。
<P>  PublicOverridesReadOnlyProperty
  TemplateGroups()AsTemplateGroupCollection
  Get
  Ifo_TemplateGroupsIsNothingThen
  ...
  EndIf
  Returno_TemplateGroups
  EndGet
  EndProperty
  在这个属性重载中,我将构建VisualStudio利用的TemplateGroupCollection。属性中的“IsNothing”反省有助于制止对这个工具不用要的从头构建。
  起首我将实例化o_TemplateGroups工具。
  o_TemplateGroups=NewTemplateGroupCollection()
  如今,我必要利用我在“敏捷标签”一节中所会商的组件变量来获得我计划的控件。
  DimctlAsEmailContact=CType(Component,EmailContact)
  稍后,我将利用这个变量。可是起首,我必需创建我要利用的响应于TemplateGroup和TemplateDefinition工具的两个工具变量。
<P>  Dimo_TemplateGroupAsTemplateGroup
  Dimo_TemplateDefinitionAsTemplateDefinition
  如今我能够入手下手界说组和模板了。
<P>  o_TemplateGroup=NewTemplateGroup("SurroundingTemplates")
  文本“SurroundingTemplates”将呈现在分类题目中,合用于我放在这个组中的一切模板界说。
  o_TemplateDefinition=NewTemplateDefinition(Me,
  "HeaderTemplate",ctl,"HeaderTemplate",False)
  o_TemplateGroup.AddTemplateDefinition_
  (o_TemplateDefinition)
  让我来具体剖析一下该TemplateDefinition机关器中的参数。第一个参数是一个增加了模板编纂功效的计划器的实例―一般是Me;第二个参数是模板名―它将显现于一个快速体例菜单或敏捷标签中。第三个参数是正在计划的控件―经由过程转换Component工具来失掉它。第四个参数是控件中模板属性的名字。参数列表最初的Boolean参数被设置为False以便指定这个模板既吸收服务器控件也吸收HTML控件。假如把它设置为True则仅同意把服务器控件(惯例Web控件)增加到模板上。
  你大概已猜出,关于你想界说的每一个模板和每一个模板组,都要反复这一操纵。终极了局是,我的o_TemplateGroups工具中添补了我的模板中界说的一切信息―而这恰是我在这个属性中所前往的内容。



  .在模板编纂体例的EmailContact控件
  如今,我从头编译并转到我的测试页面。当我右击EmailContact控件时,我将看到“EditTemplates”被增加到快速体例菜单中。子菜单下的列表将显现我在计划器类中所界说的模板组,而当我选择“SurroundingTemplates”组时,我会看到相似所示的内容。如今,你能够看到我手工地增加到这两个模板中的控件;而现实上,我如今就能够把别的控件从工具箱间接拖动到其上。再次右击鼠标并选择“EditTemplates”将前往到尺度控件视图而且在控件中显现该模板内容。
  别的还注重,一个“EditTemplates”链接也被主动地增加到该控件的敏捷标签上。假如之前不存在一个敏捷标签,那末,当我把模板编纂代码增加到计划器类上时,它会主动地为我创立一个。
  上面是完全的模板编纂代码:
<P>  PublicOverridesSubInitialize(ByValComponentAsIComponent)
  MyBase.Initialize(Component)
  Turnontemplateediting
  SetViewFlags(ViewFlags.TemplateEditing,True)
  EndSub
  Privateo_TemplateGroupsAsTemplateGroupCollection=Nothing
  PublicOverridesReadOnlyPropertyTemplateGroups()_
  AsTemplateGroupCollection
  Get
  Ifo_TemplateGroupsIsNothingThen
  o_TemplateGroups=NewTemplateGroupCollection()
  Dimo_TemplateGroupAsTemplateGroup
  Dimo_TemplateDefinitionAsTemplateDefinition
  DimctlAsEmailContact2=CType(Component,_
  EmailContact2)
  o_TemplateGroup=NewTemplateGroup(_
  "SurroundingTemplates")
  o_TemplateDefinition=NewTemplateDefinition(_
  Me,"HeaderTemplate",ctl,"HeaderTemplate",True)
  o_TemplateGroup.AddTemplateDefinition(_
  o_TemplateDefinition)
  o_TemplateDefinition=NewTemplateDefinition(_
  Me,"FooterTemplate",ctl,"FooterTemplate",True)
  o_TemplateGroup.AddTemplateDefinition(_
  o_TemplateDefinition)
  o_TemplateGroups.Add(o_TemplateGroup)
  EndIf
  Returno_TemplateGroups
  EndGet
  EndProperty
  1、主动格局化
  如今,让我们入手下手会商本文中最风趣的内容。你是不是曾把一个GridView拖动到一个表单上而且注重到在属性扫瞄器有一个标有“AutoFormat…”的链接?当你点击它时,你会失掉一个预界说格局的选择:比方Corporate,Elegant,Classic,等。现实上,跟着ASP.NET2.0刊行的一切平安控件套件(SecurityControlSuite)都供应了这个特性。读完本节后,你必定会为在你的控件中供应这类功效的简单水平而感应受惊。
  起首,我要断定我想在控件中供应甚么格局。我将经由过程创立三种格局来简化操纵。个中的两个分离称为“Monochrome”和“Colorful”。第三个(实践上是第一个)称为“NoFormat”;当把它拖动到一个表单时,它可以把控件恢复到其原始形态。
  我创立的每种格局都必要它本人的承继自System.Web.UI.Design定名空间的DesignerAutoFormat类。因而,我先从一个称为ColorfulFormat的承继自DesignerAutoFormat的类入手下手。起首,我必要为这个类供应一个缺省的机关器;而且我将在个中挪用基类的机关器,发送给它一个参数―格局称号(将呈现在列表中)。
<P>  PublicSubNew()
  MyBase.New("Colorful")
  EndSub
  接上去,我必需重载Apply办法。这个办法吸收一个Control范例的参数。我的控件计划器类将挪用这个办法,而且把我的控件实例发送到这个参数中。然后,我要把该参数转化成我的控件范例;如许以来,我就有一个可使用的强范例援用了。
<P>  PublicOverridesSubApply(_
  ByValcontrolAsSystem.Web.UI.Control)
  DimourControlAsEmailContact2=CType(control,EmailContact2)
  IfourControlIsNotNothingThen
  ...
  EndIf
  EndSub
  如今,我要设置我必要的任何属性―这一般包含一些作风属性,可是它现实上可以包含我必要的统统。因而,在“IsNotNothing”反省中,针对这个特定的格局,我只需复杂地设置我想完成的任何作风属性。列表2展现了完全的列表。
<P>  ourControl.BackColor=Drawing.Color.Aquamarine
  ourControl.BorderStyle=BorderStyle.Double
  ourControl.BorderWidth=Unit.Pixel(2)
  ourControl.BorderColor=Drawing.Color.DarkRed
  ourControl.HeadingStyle.Font.Name="arial"
  ourControl.HeadingStyle.Font.Bold=True
  ourControl.HeadingStyle.Font.Size=FontUnit.Large
  接上去,我将创立一个称为MonochromeFormat的类而且实行不异的步骤―仅在此次,我把作风属性设置为black和white以响应于一种“monochrome”格局。源码文件中的列表3展现了这个类的完全代码。
  最初,我必需创立NoFormat类。这个类遵守与前两个不异的计划;可是,我不是把作风属性值设置成各类色彩及字体,而是在一切的作风属性上挪用Reset办法。这能够把一切的作风值设置为它们的缺省形态。
  特地说一下,既然我的EmailContact控件派生自CompositeControl类,而它又派生自WebControl类;以是,我还能够在我的控件的类级上获得作风属性。这意味着:我能够具有BackColor,ForeColor等属性,并且能够间接从我的控件中存取它们而不用经由过程一个属性来完成。但是,为了复位这些作风值,我不是间接从我的控件类获得一个Reset办法,而是由WebControl类为我供应了一个ControlStyle属性,它用作响应于一切的容器作风值的出口点。注重:在复位控件的表面时,我还把Height属性设置为一个具有400个像素的缺省值。上面是完全的类:
<P>  PublicClassNoFormat
  InheritsDesignerAutoFormat
  PublicSubNew()
  MyBase.New("NoFormat")
  EndSub
  PublicOverridesSubApply(ByValcontrol_
  AsSystem.Web.UI.Control)
  DimourControlAsEmailContact2=CType(control,_
  EmailContact2)
  IfourControlIsNotNothingThen
  ourControl.ControlStyle.Reset()
  ourControl.HeadingStyle.Reset()
  ourControl.CaptionStyle.Reset()
  ourControl.FieldStyle.Reset()
  ourControl.ReadonlyFieldStyle.Reset()
  ourControl.ButtonStyle.Reset()
  ourControl.Height=Unit.Pixel(400)
  EndIf
  EndSub
  EndClass
  如今,既然我已创立了我想完成的一切格局类,那末,接上去,我必要对它们做一些实践的操纵。为此,我将再转回到控件计划器类―完成一些重载。我必要重载的属性称为AutoFormats,它前往一个System.Web.UI.Design定名空间中的DesignerAutoFormatCollection范例的工具。
  就象在敏捷标签和模板编纂部分一样,我将实例化的工具(为了经由过程属性前往之)是在类级上声明的,由于ASP.NET基本布局会卖力对它举行缓冲处置。
<P>  Privateo_AutoFormatsAs_
  DesignerAutoFormatCollection
  然后,在属性重载完成中,我能够测试工具变量是不是是一个null值。如今,我们只需复杂地利用我之前创立的每个格局类的实例来添补o_AutoFormats汇合工具。
<P>以下是援用片断:
  PublicOverridesReadOnlyPropertyAutoFormats()_
  AsDesignerAutoFormatCollection
  Get
  Ifo_AutoFormatsIsNothingThen
  o_AutoFormats=NewDesignerAutoFormatCollection
  Witho_AutoFormats
  .Add(NewNoFormat)
  .Add(NewMonochromeFormat)
  .Add(NewColorfulFormat)
  EndWith
  EndIf
  Returno_AutoFormats
  EndGet
  EndProperty
  假如我从头编译并再次测试该控件,我将看到一个称为“AutoFormat…”的链接被增加到敏捷标签的顶部。假如之前不存在敏捷标签,那末VisualStudio将主动地利用“AutoFormat…”链接在个中创立一个。你将还注重到一个“AutoFormat…”链接呈现在属性扫瞄器的底部。
  假如我点击任何一个链接,我将看到如所示的内容。选择列表中的任何一种格局从而在预览窗口中改动它;然后点击OK把此设置提交给Web表单计划界面下的控件。
  


.主动格局化屏幕
  如今,既然你已懂得了怎样举行格局化,那末接上去,你应当进修什么时候和为何举行格局化。
  我似乎听到CSS喜好者正在对本文高声叫唤。实在,我自己就是一个“层叠式样表(CSS)”迷,并在我一切的站点中利用它们。主动格局化特性在有些情形下(比方控件组)长短常有效的。比方,我们无妨思索微软的平安控件套件(SecurityControlSuite)。从中,你会看到七种Web控件可用于一个站点中觉得页面增加认证功效。个中,每种控件都供应了主动格局化功效,而且每个控件都显现一样的列表用于从当选择一个格局―这是相称不错的功效。
  试想一下我们明天已完成的一些盛行的可视化效果:比方Outlook工具栏中的很多作风,各类TreeView控件,菜单和工具栏,等。你完整能够把这个中的很多特性集成到几近任何站点的计划作风中。在这类情形下,主动格局化是一种相称有效的工具。
  如今请记着,在每个格局类中,我把作风值改动为我的一些作风属性。假如你在Web表单中使用这些格局中的任一个,那末,你将会看到这些作风值的确在属性扫瞄器中改动了。假如我想(只管我不会选择)如许做的话,那末我能够修正style属性的CssClass值,而且把一个作风表类指派给它们。这固然能够顺遂地事情,可是以后,我必要同我的控件一同公布该CSS文件,而且还要确保页面链接到它。
  假如我可以在我的控件中利用这些资本文件而不用伴同控件的DLL文件一同刊行它们,不是相称酷吗?好,上面我们来会商本文的最初一个话题―Web资本。
  1、Web资本
  Web资本是被编译到你的控件DLL中的一些嵌进式文件。Windows表单控件开辟者好久以来就具有这类才能,只是到如今它才被使用于Web范畴。让我们设想开辟一个依附于某些图象才干准确天生的控件的情况。只是复杂地公布该控件响应的DLL文件而不用思索独自公布内部图象文件,这是出格有效的。剖析一下微软供应的新的TreeWeb控件,那末你就会发明这一特性。在此,图象文件是会商利用Web资本的最好候选,只管我们还可以把它们利用于JScript文件中。
  为了申明这一成绩,我想把一个邮箱图象增加到我的EmailContact控件题目的右边。你大概已注重到,在中“CONTACTUS”题目笔墨的右边已存在一个空图象。为此,我是经由过程复杂地创立一个Image子控件而且把它增加到控件条理中的得当地位来完成的。现实上,我还创立了一个称为ShowMailIcon的属性以同意页面开辟者埋没/显现图象。
  利用惯例办法就可以创立一个HeadingImageUrl字符串属性,而且在图象控件的ImageUrl属性中设置它的值。这将同意页面开辟者把这个图象设置为他所但愿的任何内容。我批准这一办法,而我在这个控件中就利用了这类办法。但是,我更深切了一步。假如HeadingImageUrl属性不是空的,那末我利用它添补图象控件的ImageUrl属性(如前所述);可是假如该属性是空的,那末我要完成一些更酷的内容。
  在我的Web控件工程中,我有一个称为mailbox.gif的邮箱图象。我将把图象的BuildAction属性设置为EmbeddedResource(注重,我能够经由过程属性扫瞄器来完成这一点)。
  接上去,我必要存取我的工程的AssemblyInfo.vb文件。在ASP.NET1.1中,这个文件位于我的工程的根文件夹下,可是在ASP.NET2.0中,它位于我的工程文件夹下。不但云云,我还必需点击属性扫瞄器顶部的“ShowAllFiles”按钮存取这个文件。在AssemblyInfo.vb文件的底部,我必要增加以下语句:
  <Assembly:WebResource("mailbox.gif","image/gif")>
  这一句把该嵌进式文件标识为一个可用的Web资本,以便于前面的提取操纵。
  为了提取该文件,我利用了Page.ClientScript工具的GetWebResourceUrl办法。如前所述,我想使页面开辟者可以利用我本人的属性重载图象;因而我以以下体例举行提取:
<P>  IfMe.HeadingImageUrl""Then
  imgMail.ImageUrl=Me.HeadingImageUrl
  Else
  imgMail.ImageUrl=Page.ClientScript.GetWebResourceUrl(_
  Me.GetType(),"mailbox.gif")
  EndIf
  这恰是我所喜好的新的Web控件特性,由于我常常不时地在一些中央利用小图象来润色我的控件。如今,我可以嵌进它们,而且只必要我的控件的DLL文件。
  测试该控件将显现如所示的了局。



  .带有嵌进式图象的终极完成后的控件
  该Web表单利用一个HTTP处置器来检索图象而且把它天生到扫瞄器。明显,这类利用大概性远远不止此。
  2、总结
  我但愿你喜好本系列文章所先容的内容。实在,ASP.NET2.0在Web开辟方面到场了很多酷的内容,比方引进了母板页面,主题,数据源,和别的优异特性。现实上,你也能够把回调(一种新的页面特性)嵌进到控件中,从而为它们到场AJAX功效以完成更好的呼应工夫并发生一种更加丰厚的客户端体验。遗憾的是,有关这一方面的内容已非本文所及。在本文中所先容的新的控件开辟特性以后尚未几见;固然,这也是我写本文的缘故原由。如你所见,这个中的年夜多半内容都与计划时候体验相干;可是,我一向以为,进步控件的直不雅性与使之有效且可以完成既定功效一样主要。假如不简单利用,那末你乃至没法周全地利用该控件所供应的功效。
无论谁倒了对双方阵营的粉丝们也是有害无益。

admin 发表于 2015-1-20 05:00:06

ASP.net1.1和2.0在程序上的语法也有很大不同,现在2.0属于新出来的,不知道半年后会不会有3.0(说笑一下)。Windows2003系统自动支持ASP和ASP.net环境,不用安装任何程序。Asp.net属于编译语言。ASP的最大不同(ASP属于解释语言)。

再见西城 发表于 2015-2-5 08:29:20

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

仓酷云 发表于 2015-2-11 08:13:34

asp.net最主要特性包括:◆编程代码更简洁◆网站可实现的功能更强大◆运行效率高◆节省服务器的动作资源

分手快乐 发表于 2015-3-2 01:01:04

在asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家域名注册机构---时代互联(www.now.net.cn),他们早在2001年微软刚推出Asp.net时就推出了对应的Asp.net虚拟主机了,经笔者的使用测试,他提供的Asp.net性能非常的稳定,版本也会定期的更新,目前他的

老尸 发表于 2015-3-11 01:26:44

那么,ASP.Net有哪些改进呢?

因胸联盟 发表于 2015-3-17 18:08:32

asp.net空间的支持有:ASP.NET1.1/虚拟目录/MicrosoftFrontPage2000扩展/CDONTS,同时他的网站上也提供了Asp.net的使用详解和程序源代码,相信对使用ASP.NET编程的程序员来说会非常有用哦!

莫相离 发表于 2015-3-24 17:21:45

当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。
页: [1]
查看完整版本: ASP.NET编程:切磋ASP.NET 2.0中的Web控件改善手艺