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

来源:互联网 发布:万德数据库 价格 编辑:程序博客网 时间:2024/06/05 16:35
 

 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所有,转载请注明出处!

原创粉丝点击