自定义控件的构建(8)


在前面的几节基础上,现在我们开始涉足构建对象集合的控件,以GridView而言,其内部就包含了多个DataBoundField控件来表示所要显示的各个列。

首先了解名为ParseChildren的特性,其用来决定如何解析控件包含的内容:值为True时,控件所包含的内容将作为控件的属性解析,若该控件包含子控件,

则该子控件将作为外围控件的属性进行解析;当值为False时,则控件包含的内容将独立解析,且子控件将不作为属性解析。

下面则创建在ParseChildren为Ture和False的不同情况下的一个自定义控件,其功能用于页面中随机显示内容。

 
 
    [ParseChildren(false)]
    public class RotatorsContentControl:WebControl
    {
        protected override void AddParsedSubObject(object obj)
        {
            if (obj is Content)
            {
                base.AddParsedSubObject(obj);
            }
        }
        protected override void RenderContents(HtmlTextWriter writer)
        {
            Random random = new Random();
            int x = this.Controls.Count;
            int index = random.Next(x);
            this.Controls[0].RenderControl(writer);
        }
    }
 
 
public class Content:Control
    { 
    }

上面的代码中实际包含了2个控件,Content和RotatorsContentControl控件,后者从其子控件中随机选择一个Content控件并呈现在浏览器中,

注意这里的ParseChildren值为False,如果未添加该属性,Content控件将被当做RotatorsContentControl的一个属性来解析,这样会产生一个异常。

演示的关键代码:

 
 
     <myControl:RotatorsContentControl ID="RotatorsContentControl1" runat="server">
     <myControl:Content ID="Content1"  runat="server">This is an apple!myControl:Content>
     <myControl:Content ID="Content2" runat="server">This is an apple,too!
         <asp:Button ID="Button1" runat="server" Text="Button" />
     myControl:Content>
     <myControl:Content ID="Content3" runat="server">This is a  banana,too!myControl:Content>
     myControl:RotatorsContentControl>
如果ParseChildren的值为True,则要为控件添加一个引用子控件的属性。
 
 
  [ParseChildren(true,"Items")]
    public class ItemControl : Control
    {
        private ArrayList array = new ArrayList();
        [Browsable(false)]
        public ArrayList Items
        {
            get { return array; }
        }
        protected override void CreateChildControls()
        {
            Random random = new Random();
            int index = random.Next(array.Count);
            Control item = (Control)array[index];
            this.Controls.Add(item);
        }
    }
    public class Item : Control
    {
    }
 
 
     

ParseChildren的第二个参数是控件属性的名字,上面的代码设计了一个Items属性表示控件所包含的控件项。与第一个示例不同的是,这里ItemRotator控件

内所包含的控件不会自动的解析成子控件,在CreatChildControl()运行后,该控件仅包含一个子控件

演示:

 
 
 <myControl:ItemControl ID="ItemControl1" runat="server">
     <myControl:Item ID="Item1" runat="server">A
     myControl:Item>
     <myControl:Item ID="Item2" runat="server">B
     myControl:Item>
     <myControl:Item ID="Item3" runat="server">C
     myControl:Item>
    myControl:ItemControl>
事实上,控件的内容可不必解析成控件,在创建表示项集合的控件时,也可以把项表示成对象。
 
 
public class Images
    {
     
        public string Url
        {
            get;set;
        }
        public string Text
        {
            get;
            set;
        }
    }
    [ParseChildren(true, "Items")]
    public class ImageRotator : WebControl
    {
        private ArrayList array = new ArrayList();
        [Browsable(false)]
        public ArrayList Items
        {
            get { return array; }
        }
        protected override void RenderContents(HtmlTextWriter writer) 
        {
            if (array.Count > 0)
            {
                Random random = new Random();
                Images image =(Images) array[random.Next(array.Count)];
                writer.AddAttribute(HtmlTextWriterAttribute.Src, image.Url);
                writer.AddAttribute(HtmlTextWriterAttribute.Alt, image.Text);
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
        }
    }

注意这里的细微变化,Images仅仅是个类,并未从任何控件基类继承。可以看看界面中如何使用这个控件的

 
 
  <myControl:ImageRotator ID="ImageRotator1" runat="server">
    <myControl:Images  Text="image1" />
    <myControl:Images  Text="image2" />
    <myControl:Images  Text="image3" />
    myControl:ImageRotator>
将页面的Trace打开,可以发现其中的ImageRotator1中并未包含任何子控件

 

 

 

本文参考了《ASP.NET 3.5揭秘》

分类: CustomControl

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25284529/viewspace-684570/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25284529/viewspace-684570/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值