第二章 .Net 控件开发(WebForm) 开发自定义复合控件(1) 继承ComPositeControl类以及子控件

 

 1、 第一章介绍了继承Control类或WebControl类开发自定义控件,以及呈现的Html标记文本和回传功能,这章我们将上述功能委托给标准或者自定义控件的自定义控件,这种控件称为复合控件,因为它是通过其它控件组合而成。

2、 我们先看下TestControl2的RenderContent方法中的部分代码,我们把这些代码生成的Html内容委托给Asp.Net标准服务器控件Lable,TextBox和Button,那将会节约很多的时间和精力;TestControl4继承自TestControl3继承自TestControl2实现了IPostBackEventHandler和IPostBackDataHandler接口,以便才能回传,我们用Asp.Net服务器控件避免了实现这两个接口,因为它们已经实现了。

writer.Write(NameLable);

            writer.AddAttribute(HtmlTextWriterAttribute.Id, NameId);
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
            writer.AddAttribute(HtmlTextWriterAttribute.Name, NameName);
            writer.RenderBeginTag(HtmlTextWriterTag.Input);
            writer.RenderEndTag();

            writer.AddAttribute(HtmlTextWriterAttribute.Id, ShowNameId); 
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
            writer.AddAttribute(HtmlTextWriterAttribute.Value, ShowNameLable);
            writer.AddAttribute(HtmlTextWriterAttribute.Name, ShowNameName);
            writer.RenderBeginTag(HtmlTextWriterTag.Input);
            writer.RenderEndTag();

3、 正如上面所说的用现有的Asp.Net服务器控件来创建自定义控件要比从头开始创建容易的多,我们定义一个新的控件叫ComTestControl,复合控件讲很多任务委托给自控件,通过以下步骤即可实现。
(1) 继承CompositeControl;
(2) 选定自控件;
(3) 选定布局;
(4) 实现自定义容器控件;
(5) 创建容器控件;
(6) 创建容器控件的子控件;
(7) 为容器控件应用样式;
(8) 讲容器控件添加给ComTestControl控件;
(9) 呈现容器控件;
(10) 重写CreateChildControl方法;
(11) 如有必要,重写TagKey属性;
(12) 如有必要,重写CrateControlStyle方法;
(13) 公开ControlStyle属性;
(14) 重写RenderContent方法;
(15) 公开子控件属性;
(16) 公开子控件事件。
4、 第一步,继承CompositeControl。这个类为每个符合控件提供了必须支持的基本特性,必须继承,这样才可以避免重新实现那些本可轻松从基类继承的特性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;

namespace WebFormControl
{
    public class ComTestControl:CompositeControl
    {
    }
}

5、 第二步,选定子控件。我们主要用到3个服务器控件作为子控件,并命名Lbl_Name(Lable控件)、Txt_Name(TextBox控件)、Btn_Show(Button控件)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;

namespace WebFormControl
{
    public class ComTestControl:CompositeControl
    {
        Label Lbl_Name;
        TextBox Txt_Name;
        Button Btn_Show;
    }
}

6、 第三步,选定布局。CompositeControl为其子控件选用一个表格布局,每个单元格内包含一个子控件,为了便于说明用单元格数字标识。

Lbl_Name-子控件-单元格1

Txt_Name-子控件-单元格2

Btn_Show-子控件-单元格3

7、 第四步,实现自定义容器控件。由于CompositeControl使用了表格为子控件布局,所以子控件最合适的容器就是TableCell控件,然而TableCell控件无法满足我们的需要:第一,控件没有实现INamingContainer接口,这个接口是个标记接口,无任何属性和方法;第二,控件没有唯一定位或者识别单元格集合中每个单元格的属性。了解正在处理的单元格非常重要,因为每个单元格包含不同的子控件。因此,我们定义继承TableCell和实现INamingContainer接口的容器控件叫ComContianer,并公开个Container属性,该属性值可以唯一定位或者识别单元格集合中的每个单元格,枚举值对应第三步中的单元格编号。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace WebFormControl
{
    public class ComContainer : TableCell, INamingContainer
    {
        private ContainerType containertype;

        public ContainerType ContainerType
        {
            get { return containertype; }
        }

        public ComContainer(ContainerType containertype)
        {
            this.containertype = containertype;
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WebFormControl
{
    public enum ContainerType
    {
        UserLable=1,
        UserTextBox=2,
        ShowButton=3
    }
}

8、 第五步,创建容器控件。在ComTestControl类里面封装了CreateContaint方法。

 protected virtual ComContainer CreateContainer(ContainerType containertype)
        {
            return new ComContainer(containertype);
        }

9、 第六步,创建容器控件的子控件。在子控件添加到Controls集合之前,需要初始化子控件。因为如果在添加到Controls后在初始化,那么这些初始的属性值讲存储在视图状态中。这样会不必要地增加自定义控件视图状态大小。

protected  virtual void CreateContainerChildControl(ComContainer container)
        {
            switch (container.ContainerType)
            {
                case ContainerType.UserLable:
                    Lbl_Name = new Label();
                    Lbl_Name.Width = Unit.Percentage(100);
                    Lbl_Name.ID = "Lbl_Name";
                    Lbl_Name.Text = "姓?名?";
                    container.Controls.Add(Lbl_Name);
                    break;
                case ContainerType.UserTextBox:
                    Txt_Name = new TextBox();
                    Txt_Name.ID = "Txt_Name";
                    container.Controls.Add(Txt_Name);
                    break;
                case ContainerType.ShowButton:
                    Btn_Show = new Button();
                    Btn_Show.ID = "Btn_Show";
                    container.Controls.Add(Btn_Show);
                    break; 
            }
        }

10、 看下下图就很好理解创建容器和创建容器子控件了,这章设计到的方法太多了。

代码下载地址:点击下载

本博客内容有些来源于网络或书籍如果侵害到你的权益,请及时联系我(hch458458@vip.qq.com)
版权归nethch所有,转载请注明出处!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值