zoukankan      html  css  js  c++  java
  • ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

     第四章 组合控件开发CompositeControl

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

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

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

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

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

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

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

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

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

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

         

              大家先看看效果:

         

              

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

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

              下面我们就来开发:

              

              首先,还是先继承CompositeControl;

    1  public class Login:CompositeControl

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

              

              


    1  #region 要组合的控件
    2         Label lbUserName;
    3         Label lbUserPassward;
    4         TextBox txtUserName;
    5         TextBox txtUserPassward;
    6         Button submitButton;
    7         #endregion

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

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

    控件的。如下:

         

              


     1   #region 重写方法CreateChildControls
     2 
     3         protected override void CreateChildControls()
     4         {
     5             //清空控件,大家可以理解为:初始化一张白纸,好让我们来画画
     6 
     7             Controls.Clear();
     8 
     9            //初始化控件lbUserName
    10             lbUserName = new Label();
    11             lbUserName.Text = "用户名:";
    12             lbUserName.ID = "lbUserName";
    13             //把控件添加到我们的组合控件中
    14             Controls.Add(lbUserName);
    15 
    16             //初始化控件lbUserPassward
    17             lbUserPassward = new Label();
    18             lbUserPassward.Text = "密  码:";
    19             lbUserPassward.ID = "lbUserPassward";
    20             Controls.Add(lbUserPassward);
    21 
    22               //初始化控件txtUserName 
    23 
    24             txtUserName = new TextBox();
    25             txtUserName.ID = "txtUserName";
    26             txtUserName.Width = Unit.Percentage(60);
    27             Controls.Add(txtUserName);
    28           
    29             //初始化控件txtUserPassward 
    30             txtUserPassward = new TextBox();
    31             txtUserPassward.ID = "txtUserPassward";
    32             txtUserPassward.Width = Unit.Percentage(60);
    33             Controls.Add(txtUserPassward);
    34 
    35             //初始化控件 submitButton  
    36             submitButton  = new Button();
    37             submitButton.Text = "提交";
    38             submitButton.CommandName = "Validate";
    39             Controls.Add(submitButton);
    40             
    41             告诉编译器,控件已经初始化了
    42             ChildControlsCreated = true;
    43         }
    44         #endregion

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

     

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

     

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

     

     

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

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

              属性,事件!!!

              

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

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

              改前的图:                                                       改后的图

               

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

              怎么做?

                   

              也很简单的:如下:

              


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

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

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

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

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

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

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

              


    1 protected override void RenderContents(HtmlTextWriter writer)

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

             


    1  protected override HtmlTextWriterTag TagKey
    2         {
    3             get
    4             {
    5                 return HtmlTextWriterTag.Table;
    6             }
    7         }

              

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

              


     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 
    10             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    11             txtUserName.RenderControl(writer);
    12             writer.RenderBeginTag();
    13 
    14             writer.RenderBeginTag();//tr的结束
    15 
    16             //***********************************************
    17 
    18             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    19 
    20             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    21             lbUserPassward .RenderControl(writer);
    22             writer.RenderEndTag();//td的结束
    23 
    24             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    25             txtUserPassward .RenderControl(writer);
    26             writer.RenderBeginTag();
    27 
    28             writer.RenderBeginTag();//tr的结束
    29            
    30             //***********************************************
    31 
    32             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    33 
    34             writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
    35             writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
    36             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    37             submitButton.RenderControl(writer);
    38             writer.RenderBeginTag();
    39 
    40             writer.RenderBeginTag();//tr的结束
    41 
    42                       
    43 
    44 
    45         }

         

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

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

            完整的代码:如下:


      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(60);
     45             Controls.Add(txtUserName);
     46 
     47             txtUserPassward = new TextBox();
     48             txtUserPassward.ID = "txtUserPassward";
     49             txtUserPassward.Width = Unit.Percentage(60);
     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();
    100                 submitButton = value;
    101             }
    102         }
    103 
    104 
    105         #endregion
    106 
    107         #region 组合控件呈现的样式
    108         protected override HtmlTextWriterTag TagKey
    109         {
    110             get
    111             {
    112                 return HtmlTextWriterTag.Table;
    113             }
    114         }
    115 
    116         protected override void RenderContents(HtmlTextWriter writer)
    117         {
    118 
    119             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    120 
    121             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    122             lbUserName.RenderControl(writer);
    123             writer.RenderEndTag();//td的结束
    124 
    125             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    126             txtUserName.RenderControl(writer);
    127             writer.RenderBeginTag();
    128 
    129             writer.RenderBeginTag();//tr的结束
    130 
    131             //***********************************************
    132 
    133             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    134 
    135             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    136             lbUserPassward .RenderControl(writer);
    137             writer.RenderEndTag();//td的结束
    138 
    139             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    140             txtUserPassward .RenderControl(writer);
    141             writer.RenderBeginTag();
    142 
    143             writer.RenderBeginTag();//tr的结束
    144            
    145             //***********************************************
    146 
    147             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    148 
    149             writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
    150             writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
    151             writer.RenderBeginTag(HtmlTextWriterTag.Td);
    152             submitButton.RenderControl(writer);
    153             writer.RenderBeginTag();
    154 
    155             writer.RenderBeginTag();//tr的结束
    156 
    157                       
    158 
    159 
    160         }
    161         #endregion
    162 
    163         
    164 
    165     }
    166 }
    167 
  • 相关阅读:
    attempted to return null from a method with a primitive return type (Double).
    window7 虚拟机安装
    DB 与oracle 批量新增的写法
    oracle 修改表
    备份还原oracle数据库
    oracle数据库的字符集更改
    IMP-00013
    oracle创建用户授权权限
    java中添加定时任务
    程序在运行过程中变量的保存位置与生命周期
  • 原文地址:https://www.cnblogs.com/xie/p/1401306.html
Copyright © 2011-2022 走看看