构建自定义控件之四——控件属性集合

构建更复杂的控件时,需要表示对象集合。比如: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.WebControlSystem.Web.UI.WebControl继承时默认为true

代码示例:创建一个内容滚动控件,在页面随机的显示内容。创建此控件有两种方法,分别在ParseChildrentrueflase情况下。

ContentRotator.cs —— ParseChildrenflase

ItemRotator.cs——ParseChildren(true,”Items”)//第二个参数是某个属性的变量名

ImageRotator.cs——ParseChildren(true,”ImageItems”)

ContentRotator.cs控件实际上包含了两个控件:ContentRotatorContent控件。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集合。

 


using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace JerryShi.Controls
{
    [ParseChildren(
false)]
    
public class ContentRotator : WebControl
    
{
        
protected override void AddParsedSubObject(object obj)
        
{
            
//must be Conten control,so that add to Controls collection
            if (obj is Content)
            
{
                
base.AddParsedSubObject(obj);
            }
            
        }


        
protected override void RenderContents(HtmlTextWriter writer)
        
{
            Random random 
= new Random();
            
int index = random.Next(this.Controls.Count);
            
this.Controls[index].RenderControl(writer);
        }

    }


    
public class Content : Control
    
{ }
}

4.3使用ControlBuilder

AddParsedSubObject()方法外的更多控制,通过给控件关联一个自定义的ControlBuilder类来修改控件解析内容的行为。

ControlBuilder类支持的最有用的方法:

AllowWhiteSpaceLiterals()——删除控件内容两端的空白

AppendLiteralString()——删除控件内容中的所有空白

GetChildControlType()——指定某种标签解析成哪种控件,可以把任意标签映射成任意控件

代码示例:ServerTab.cs

 


using System;
using System.Collections;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace JerryShi.Controls
{
    [ControlBuilder(
typeof(ServerTabsBuilder))]
    [ParseChildren(
false)]
    
public class ServerTabs:WebControl,IPostBackEventHandler
    
{
        
public int SelectedTabIndex
        
{
            
get
            
{
                
if (ViewState["SelectedTabIndex"== null)
                
{
                    
return 0;
                }

                
else
                
{
                    
return (int)(ViewState["SelectedTabIndex"]);
                }

            }

            
set
            
{
                ViewState[
"SelectedTabIndex"= value;
            }

        }


        
protected override HtmlTextWriterTag TagKey
        
{
            
get
            
{
                
return HtmlTextWriterTag.Div;
            }

        }


        
protected override void AddParsedSubObject(object obj)
        
{
            
if (obj is ServerTab)
                
base.AddParsedSubObject(obj);
        }


        
protected override void RenderContents(HtmlTextWriter writer)
        
{
            
for (int i = 0; i < this.Controls.Count; i++)
            
{
                ServerTab tab 
= (ServerTab)this.Controls[i];
                
string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, i.ToString());

                
if (SelectedTabIndex == i)
                
{
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, 
"tab selectedTab");
                }

                
else
                
{
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, 
"tab");
                }

                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef);
                writer.RenderBeginTag(HtmlTextWriterTag.A);
                writer.Write(tab.Text);
                writer.RenderEndTag();
// A
                writer.RenderEndTag();// div
            }


            writer.Write(
"<br style='clear:both' />");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, 
"tabContents");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            
this.Controls[SelectedTabIndex].RenderControl(writer);
            writer.RenderEndTag();
        }



        
#region IPostBackEventHandler 成员

        
public void RaisePostBackEvent(string eventArgument)
        
{
            SelectedTabIndex 
= Int32.Parse(eventArgument);
        }


        
#endregion

    }


    
public class ServerTabsBuilder : ControlBuilder
    
{
        
public override Type GetChildControlType(string tagName, IDictionary attribs)
        
{
            
if (String.Compare(tagName, "tab"true).Equals(0))
            
{
                
return typeof(ServerTab);
            }

            
else
            
{
                
return null;
            }

        }

    }


    
public class ServerTab : Control
    
{
        
private string _Text;

        
public string Text
        
{
            
get return _Text; }
            
set { _Text = value; }
        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值