ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

时间:2023-02-21 12:08:58

原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

第四章 组合控件开发CompositeControl

大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基

类:Control,WebControl,还有一个就是今天要说的CompositeControl。

系列文章链接:

ASP.NET自定义控件组件开发 第一章 待续

ASP.NET自定义控件组件开发 第一章 第二篇 接着待续

ASP.NET自定义控件组件开发 第一章 第三篇

ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件

ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

ASP.NET自定义控件组件开发 第五章 模板控件开发

ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

ASP.NET2.0组件控件开发视频 初体验

大家也许还记得,之前的开发的控件基本上都是我们自己从头到尾的写一些控件的标记,如<table.....>之类的,

而且还有一个大的问题:我们为了使得我们的控件更加的好用,专业,我们还实现了大量的接口,和自己写很多的事件.这样

开发控件的时间就加大了。其实我们可以利用ASP.NET中已经有的控件,经过我们包装,实现我们自定义控件。大家可能认

为这和用户控件差不多的,但是继承CompositeConytol的控件的自定义控件的灵活性和复用行更好,而且还还添加样式。

还一个更加重要的就是我们不必要实现接口,比如,引发回传的IPostBackEventHandler接口,接受数据的

IPostBackDataHandler接口。大家还记得我们之前开发控件中的的那个Button还要申明name为 this.UniqueID ,

现在我们都不需要了,因为我们要包装的那些服务器的控件,如TextBox,他们都已经实现了这些。

本章准备开发一个大家都熟知的Login登录控件。

大家先看看效果:

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

其实分析起来,这个控件是由一些已有的控件组合而成的,分别是:

两个Label,两个TextBox,和一个Button

下面我们就来开发:

首先,还是先继承CompositeControl;

Code
  public class Login:CompositeControl

然后把就申明我们要组合的控件,如上所说的:

Code
  #region 要组合的控件
         Label lbUserName;
         Label lbUserPassward;
         TextBox txtUserName;
         TextBox txtUserPassward;
         Button submitButton;
         #endregion

把控件申明了之后只要初始化,并且将这些控件整合成我们的Login 控件就可以了。这么做呢?

其实开发组合控件很简单,一般只要重写一个方法就可以了。这个方法就是来初始化并且整合那些已经申明了的小

控件的。如下:

Code
 1   #region 重写方法CreateChildControls
 2 
 3         protected override void CreateChildControls()
 4         {
 5             //清空控件,大家可以理解为:初始化一张白纸,好让我们来画画
 6 
 7             Controls.Clear();
 8 
 9            //初始化控件lbUserName
             lbUserName = new Label();
             lbUserName.Text = "用户名:";
             lbUserName.ID = "lbUserName";
             //把控件添加到我们的组合控件中
             Controls.Add(lbUserName);
 
             //初始化控件lbUserPassward
             lbUserPassward = new Label();
             lbUserPassward.Text = "密  码:";
             lbUserPassward.ID = "lbUserPassward";
             Controls.Add(lbUserPassward);
 
               //初始化控件txtUserName 
 
             txtUserName = new TextBox();
             txtUserName.ID = "txtUserName";
             txtUserName.Width = Unit.Percentage();
             Controls.Add(txtUserName);
           
             //初始化控件txtUserPassward 
             txtUserPassward = new TextBox();
             txtUserPassward.ID = "txtUserPassward";
             txtUserPassward.Width = Unit.Percentage();
             Controls.Add(txtUserPassward);
 
             //初始化控件 submitButton  
             submitButton  = new Button();
             submitButton.Text = "提交";
             submitButton.CommandName = "Validate";
             Controls.Add(submitButton);
             
             告诉编译器,控件已经初始化了
             ChildControlsCreated = true;
         }
         #endregion

大家特别要注意,最后的那句ChildControlsCreated属性,一定要申明,因为在页面的声明周期的任何时候可能调

用上面的那个方法,如果不申明ChildControlsCreated,那么这个方法就会被反复的调用,那么我们控件的状态都会丢失。

如果申明了ChildControlsCreated=true,那么这个方法就调用一次。

经过上面的步骤之后,其实我们的控件就已经开发完成了。

可能我们还想进一步的向我们ASP.NET的标准的Login控件靠拢.那么我们的控件还缺少什么?

属性,事件!!!

以前我们定义属性都是用的ViewState["..."],但是这里就不同了。因为我们的控件是有很多的小的控件组

合起来的,比如,我们修改“用户名:”的那个Label,我们想改的是那个Label的属性,还是看看效果图:

改前的图:                                                       改后的图

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl  ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

就是说,我们想把子控件的属性如Text,name等等,把这些属性上升呈现为组合控件Login的属性。

怎么做?

也很简单的:如下:

Code
 1  public string UserNameLabelText
 2         {
 3             get
 4             {
 5                 EnsureChildControls();
 6                 return lbUserName.Text;
 7             }
 8             set
 9             {
                 EnsureChildControls();
                 lbUserName.Text = value;
             }
         }

这样我们就把那个显示用户名的Label的Text属性显示为了Login控件的UserNameLabelText属性。大家要注意

EnsureChildControls(); 这个方法的调用。其实是个保险的:确保我们要显示属性的那个控件已经创建,已经初始化了。

大家可以根据需要显示更加多的属性。也可以自己定义一些属性,还是像以前那样,可以用ViewState[''.."]

如果到这里为止,就差不多了。大家可以按按照上面的方法来写控件。

大家可以看见,控件的呈现很乱。那些Label.TextBox都布局的很乱。其实你可以根据需要来将上面的那些控件排列

的更加好看些,只要重写一个方法就行了:

Code
 protected override void RenderContents(HtmlTextWriter writer)

还是像之前一样,我们想把控件用一个Table来布局,先这样

Code
  protected override HtmlTextWriterTag TagKey
         {
             get
             {
                 return HtmlTextWriterTag.Table;
             }
         }

然后再把那些Label,TextBox,Button放到table的行和列中就行了。如下:

Code
 1 protected override void RenderContents(HtmlTextWriter writer)
 2         {
 3 
 4             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 5 
 6             writer.RenderBeginTag(HtmlTextWriterTag.Td);
 7             lbUserName.RenderControl(writer);
 8             writer.RenderEndTag();//td的结束
 9 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtUserName.RenderControl(writer);
             writer.RenderBeginTag();
 
             writer.RenderBeginTag();//tr的结束
 
             //***********************************************
 
             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             lbUserPassward .RenderControl(writer);
             writer.RenderEndTag();//td的结束
 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtUserPassward .RenderControl(writer);
             writer.RenderBeginTag();
 
             writer.RenderBeginTag();//tr的结束
            
             //***********************************************
 
             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 
             writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "");
             writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             submitButton.RenderControl(writer);
             writer.RenderBeginTag();
 
             writer.RenderBeginTag();//tr的结束
 
                       
 
 
         }

这样,我们的控件就写完了。

我们的控件还差事件。我们在下篇将“事件的冒泡”。

顺便做个调查:大家想看开发控件的视频吗,我正在录制。

完整的代码:如下:

Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Web;
  5 using System.Web.UI;
  6 using System.Web.UI.WebControls;
  7 using System.ComponentModel;
  8 
  9 namespace LoginControl
 10 {
 11     public class Login:CompositeControl,IPostBackDataHandler
 12     {
 13         #region 要组合的控件
 14         Label lbUserName;
 15         Label lbUserPassward;
 16         TextBox txtUserName;
 17         TextBox txtUserPassward;
 18         Button submitButton;
 19         #endregion
 20        
 21 
 22         #region 重写方法CreateChildControls
 23 
 24         protected override void CreateChildControls()
 25         {
 26             Controls.Clear();
 27 
 28            //初始化控件lbUserName
 29             lbUserName = new Label();
 30             lbUserName.Text = "用户名:";
 31             lbUserName.ID = "lbUserName";
 32             //把控件添加到我们的组合控件中
 33             Controls.Add(lbUserName);
 34 
 35             //初始化控件lbUserPassward
 36             lbUserPassward = new Label();
 37             lbUserPassward.Text = "密  码:";
 38             lbUserPassward.ID = "lbUserPassward";
 39             Controls.Add(lbUserPassward);
 40            
 41 
 42             txtUserName = new TextBox();
 43             txtUserName.ID = "txtUserName";
 44             txtUserName.Width = Unit.Percentage();
 45             Controls.Add(txtUserName);
 46 
 47             txtUserPassward = new TextBox();
 48             txtUserPassward.ID = "txtUserPassward";
 49             txtUserPassward.Width = Unit.Percentage();
 50             Controls.Add(txtUserPassward);
 51 
 52             submitButton  = new Button();
 53             submitButton.Text = "提交";
 54             submitButton.CommandName = "Validate";
 55             Controls.Add(submitButton);
 56 
 57             ChildControlsCreated = true;
 58         }
 59         #endregion
 60         #region 将组合的子控件的属性 呈现为 组合控件的属性
 61 
 62         public string UserNameLabelText
 63         {
 64             get
 65             {
 66                 EnsureChildControls();
 67                 return lbUserName.Text;
 68             }
 69             set
 70             {
 71                 EnsureChildControls();
 72                 lbUserName.Text = value;
 73             }
 74         }
 75 
 76         public string UserPasswardLabelText
 77         {
 78             get
 79             {
 80                 EnsureChildControls();
 81                 return lbUserPassward.Text;
 82             }
 83             set
 84             {
 85                 EnsureChildControls();
 86                 lbUserPassward.Text = value;
 87             }
 88         }
 89 
 90         public string SubmitButtonText
 91         {
 92             get
 93             {
 94                 EnsureChildControls();
 95                 return submitButton.Text;
 96             }
 97             set
 98             {
 99                 EnsureChildControls();
                 submitButton = value;
             }
         }
 
 
         #endregion
 
         #region 组合控件呈现的样式
         protected override HtmlTextWriterTag TagKey
         {
             get
             {
                 return HtmlTextWriterTag.Table;
             }
         }
 
         protected override void RenderContents(HtmlTextWriter writer)
         {
 
             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             lbUserName.RenderControl(writer);
             writer.RenderEndTag();//td的结束
 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtUserName.RenderControl(writer);
             writer.RenderBeginTag();
 
             writer.RenderBeginTag();//tr的结束
 
             //***********************************************
 
             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             lbUserPassward .RenderControl(writer);
             writer.RenderEndTag();//td的结束
 
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtUserPassward .RenderControl(writer);
             writer.RenderBeginTag();
 
             writer.RenderBeginTag();//tr的结束
            
             //***********************************************
 
             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 
             writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "");
             writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             submitButton.RenderControl(writer);
             writer.RenderBeginTag();
 
             writer.RenderBeginTag();//tr的结束
 
                       
 
 
         }
         #endregion
 
         
 
     }
 }
 

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl的更多相关文章

  1. ASP&period;NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl  后篇 --事件冒泡 系列文章链接: ASP.NET ...

  2. ASP&period;NET自定义控件组件开发 第五章 模板控件开发

    原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  3. ASP&period;NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  4. ASP&period;NET自定义控件组件开发 第三章 为控件添加事件 后篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...

  5. 『Asp&period;Net 组件』第一个 Asp&period;Net 服务器组件:自己的文本框控件

    代码: using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace DemoWebControl ...

  6. Andriod 自定义控件之创建可以复用的组合控件

    前面已学习了一种自定义控件的实现,是Andriod 自定义控件之音频条,还没学习的同学可以学习下,学习了的同学也要去温习下,一定要自己完全的掌握了,再继续学习,贪多嚼不烂可不是好的学习方法,我们争取学 ...

  7. Android开发学习笔记-自定义组合控件的过程

    自定义组合控件的过程 1.自定义一个View 一般来说,继承相对布局,或者线性布局 ViewGroup:2.实现父类的构造方法.一般来说,需要在构造方法里初始化自定义的布局文件:3.根据一些需要或者需 ...

  8. 安全控件开发原理分析 支付宝安全控件开发 C&plus;&plus;

    浏览器安全控件是如果支付宝一样结合web程序密码数据安全处理的程序,采用C++语言开发 通常的安全控件分为两种,一种是指支持IE内核的浏览器,一种支持所有内核的浏览器,支付宝采用的是支持所有内核的浏览 ...

  9. 【Android】13&period;0 UI开发(四)——列表控件RecyclerView的横向布局排列实现

    1.0 新建项目,由于ListView的局限性,RecyclerView是一种很好取代ListView的控件,可以灵活实现多种布局. 2.0 新建项目RecyclerviewTest,目录如下: 3. ...

随机推荐

  1. Java并发编程核心方法与框架-TheadPoolExecutor的使用

    类ThreadPoolExecutor最常使用的构造方法是 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAli ...

  2. Drozer安装

    (1)JDK安装 http://www.cnblogs.com/linbc/p/4319509.html http://blog.csdn.net/qq_31988895/article/detail ...

  3. Gym 101673F Keeping On Track

    原题传送门 题意:给定一颗n+1(n≤10000)个结点的树(当然有n条边辣),定义一个结点为critical,当且仅当除去这个点及与其相连的边后,所有不相连的结点对数量最多.现在保证有且仅有一个结点 ...

  4. WEB学习笔记11-高可读性的HTML之如何设置网页标题层级

    标题标签指的是<h1>~<h6>这6个标签,统称为<hx>标签. (1)在页面内容的标题部分使用<hx>标签 <h1 class="re ...

  5. 抽象语法树&lpar;AST&rpar;

    AST描述 在计算机科学中,抽象语法树(AST)或语法树是用编程语言编写的源代码的抽象语法结构的树表示.树的每个节点表示在源代码中出现的构造.语法是“抽象的”,因为它不代表真实语法中出现的每个细节,而 ...

  6. volatile特性

    volatile保证可见性 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作的可见性,即一个线程修改了某个变量 ...

  7. UV-Sprite动画

    [UV-Sprite动画] 下文以单行Sprite纹理作为动画贴图.首先需要输入纹理宽度.Sprint数量.速度: 计算每个Sprite的像素宽与UV宽: 根据_Time,计算当前显示第几个Sprit ...

  8. 探究Activity&lpar;1&rpar;--Activity的基本用法

    一.Activity是什么 Activity(活动)是最容易吸引用户的地方,它是一种可以包含用户界面的组件,主要用于和用户进行交互.一个应用程序中应该包括零个或多个Activity. 二.Activi ...

  9. Eclipse Debug 使用

      Eclipse的debug模式:代码调试 * Eclipse或MyEclipse就是java的开发工具 * Eclipse开源的.免费的Java开发工具 * MyEclipse基于Eclipse开 ...

  10. C&num; 继承(4)

    接上章: class NameList { public NameList() => Console.WriteLine("这个是NameList的构造函数"); publi ...