构建更复杂的控件时,需要表示对象集合。比如:DropDownList中的ListItem项,GridView中的DataBoundField项。
4.1使用ParseChildren属性
本节示例将会创建多内容滚动控件,可以随机显示HTML内容;会创建一个服务器端选项卡控件,可以生成内容的选项卡视图。
·使用ParseChildren 属性,该属性决定如何分析控件包含的内容。
当ParseChildren设置为true时,控件所包含的内容作为控件的属性进行分析。如果该空间含有子控件,那么子控件被当作外围控件的属性来分析。
当ParseChildren设置为flase时,不会把子控件当作属性分析,控件包含的内容将独立分析。
Control类的ParseChildren属性默认为flase,但是WebControl类继承并重写了该默认值为true。因此,当我们从System.Web.UI.Control继承时,默认为flase,当我们从System.Web.UI.WebControl或System.Web.UI.WebControl继承时默认为true。
代码示例:创建一个内容滚动控件,在页面随机的显示内容。创建此控件有两种方法,分别在ParseChildren为true或flase情况下。
ContentRotator.cs —— ParseChildren:flase
ItemRotator.cs——ParseChildren(true,”Items”)//第二个参数是某个属性的变量名
ImageRotator.cs——ParseChildren(true,”ImageItems”)
ContentRotator.cs控件实际上包含了两个控件:ContentRotator和Content控件。ContentRotator控件从他的子控件中随机的选择一个Content控件,并把起呈现到浏览器。
如果PareseChildren设为true,则Content控件会被作为ContentRotator控件的属性来分析,会产生异常。此时需要为控件添加一个引用所含子控件的属性。
ItemRotator控件不同于ContentRotator控件的是其所包含的子控件不会自动解析成子控件,ItemRotator通过CreateChildControls()方法来创建自己的子控件,而ContentRotator只是在向客户端RenderContent()的时候确定显示或者不显示。
ImageRotator控件中的项ImageItem并不是一个控件而是一个普通类。它仅仅表示一个属性。从开启了跟踪的页面可以查看ImageRotator控件并不包含任何子控件。
4.2使用AddParsedSubObject()方法
当ParseChildren=false时,控件内容均为控件的子控件(Controls),其中的空格回车,都会添加到Controls集合。控件内的任何非服务器端控件都会解析成Literal控件,并没有进行过滤。
AddParsedSubObject()方法在每个子控件添加到Controls集合时被调用,通过重写该方法,可以组织某种控件添加到Controls集合。
代码示例:ContentRotator.cs,判断控件是否是Content控件,是则添加到Controls集合。
4.3使用ControlBuilder
除AddParsedSubObject()方法外的更多控制,通过给控件关联一个自定义的ControlBuilder类来修改控件解析内容的行为。
ControlBuilder类支持的最有用的方法:
AllowWhiteSpaceLiterals()——删除控件内容两端的空白
AppendLiteralString()——删除控件内容中的所有空白
GetChildControlType()——指定某种标签解析成哪种控件,可以把任意标签映射成任意控件
代码示例:ServerTab.cs