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

本文介绍如何使用ASP.NET中的CompositeControl基类来自定义Login控件,包括控件的组合、属性设置及布局方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

http://www.chinaitz.com/html/2009/0307/398750.html

 

大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基类:Control,WebControl,还有一个就是今天要说的CompositeControl。

  大家也许还记得,之前的开发的控件基本上都是我们自己从头到尾的写一些控件的标记,如<table.....>之类的,而且还有一个大的问题:我们为了使得我们的控件更加的好用,专业,我们还实现了大量的接口,和自己写很多的事件.这样开发控件的时间就加大了。其实我们可以利用ASP.NET中已经有的控件,经过我们包装,实现我们自定义控件。大家可能认为这和用户控件差不多的,但是继承CompositeConytol的控件的自定义控件的灵活性和复用行更好,而且还还添加样式。

  还一个更加重要的就是我们不必要实现接口,比如,引发回传的IPostBackEventHandler接口,接受数据的IPostBackDataHandler接口。大家还记得我们之前开发控件中的的那个Button还要申明name为 this.UniqueID ,现在我们都不需要了,因为我们要包装的那些服务器的控件,如TextBox,他们都已经实现了这些。

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

  大家先看看效果:

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

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

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

  下面我们就来开发:

  首先,还是先继承CompositeControl;

1 publicclassLogin:CompositeControl

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

1 #region要组合的控件
2    LabellbUserName;
3    LabellbUserPassward;
4    TextBoxtxtUserName;
5    TextBoxtxtUserPassward;
6    ButtonsubmitButton;
7    #endregion

 

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

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

1 #region重写方法CreateChildControls
2
3    protectedoverridevoidCreateChildControls()
4    {
5      //清空控件,大家可以理解为:初始化一张白纸,好让我们来画画
6
7      Controls.Clear();
8
9      //初始化控件lbUserName
10      lbUserName=newLabel();
11      lbUserName.Text="用户名:";
12      lbUserName.ID="lbUserName";
13      //把控件添加到我们的组合控件中
14      Controls.Add(lbUserName);
15
16      //初始化控件lbUserPassward
17      lbUserPassward=newLabel();
18      lbUserPassward.Text="密 码:";
19      lbUserPassward.ID="lbUserPassward";
20      Controls.Add(lbUserPassward);
21
22       //初始化控件txtUserName
23
24      txtUserName=newTextBox();
25      txtUserName.ID="txtUserName";
26      txtUserName.Width=Unit.Percentage(60);
27      Controls.Add(txtUserName);
28     
29      //初始化控件txtUserPassward
30      txtUserPassward=newTextBox();
31      txtUserPassward.ID="txtUserPassward";
32      txtUserPassward.Width=Unit.Percentage(60);
33      Controls.Add(txtUserPassward);
34
35      //初始化控件submitButton 
36      submitButton =newButton();
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的属性,还是看看效果图:

  改前的图:                            改后的图

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

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

  怎么做?

  也很简单的:如下:

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

 

这样我们就把那个显示用户名的Label的Text属性显示为了Login控件的UserNameLabelText属性。大家要注意EnsureChildControls(); 这个方法的调用。其实是个保险的:确保我们要显示属性的那个控件已经创建,已经初始化了。

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

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

  大家可以看见,控件的呈现很乱。那些Label.TextBox都布局的很乱。其实你可以根据需要来将上面的那些控件排列的更加好看些,只要重写一个方法就行了:

1protectedoverridevoidRenderContents(HtmlTextWriterwriter)

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

1 protectedoverrideHtmlTextWriterTagTagKey
2    {
3      get
4      {
5        returnHtmlTextWriterTag.Table;
6      }
7    }

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

1protectedoverridevoidRenderContents(HtmlTextWriterwriter)
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    }

 

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

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

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

  完整的代码:如下:

 1usingSystem;
 2usingSystem.Collections.Generic;
 3usingSystem.Text;
 4usingSystem.Web;
 5usingSystem.Web.UI;
 6usingSystem.Web.UI.WebControls;
 7usingSystem.ComponentModel;
 8
 9namespaceLoginControl
10{
11  publicclassLogin:CompositeControl,IPostBackDataHandler
12  {
13    #region要组合的控件
14    LabellbUserName;
15    LabellbUserPassward;
16    TextBoxtxtUserName;
17    TextBoxtxtUserPassward;
18    ButtonsubmitButton;
19    #endregion
20    
21
22    #region重写方法CreateChildControls
23
24    protectedoverridevoidCreateChildControls()
25    {
26      Controls.Clear();
27
28      //初始化控件lbUserName
29      lbUserName=newLabel();
30      lbUserName.Text="用户名:";
31      lbUserName.ID="lbUserName";
32      //把控件添加到我们的组合控件中
33      Controls.Add(lbUserName);
34
35      //初始化控件lbUserPassward
36      lbUserPassward=newLabel();
37      lbUserPassward.Text="密 码:";
38      lbUserPassward.ID="lbUserPassward";
39      Controls.Add(lbUserPassward);
40      
41
42      txtUserName=newTextBox();
43      txtUserName.ID="txtUserName";
44      txtUserName.Width=Unit.Percentage(60);
45      Controls.Add(txtUserName);
46
47      txtUserPassward=newTextBox();
48      txtUserPassward.ID="txtUserPassward";
49      txtUserPassward.Width=Unit.Percentage(60);
50      Controls.Add(txtUserPassward);
51
52      submitButton =newButton();
53      submitButton.Text="提交";
54      submitButton.CommandName="Validate";
55      Controls.Add(submitButton);
56
57      ChildControlsCreated=true;
58    }
59    #endregion
60    #region将组合的子控件的属性呈现为组合控件的属性
61
62    publicstringUserNameLabelText
63    {
64      get
65      {
66        EnsureChildControls();
67        returnlbUserName.Text;
68      }
69      set
70      {
71        EnsureChildControls();
72        lbUserName.Text=value;
73      }
74    }
75
76    publicstringUserPasswardLabelText
77    {
78      get
79      {
80        EnsureChildControls();
81        returnlbUserPassward.Text;
82      }
83      set
84      {
85        EnsureChildControls();
86        lbUserPassward.Text=value;
87      }
88    }
89
90    publicstringSubmitButtonText
91    {
92      get
93      {
94        EnsureChildControls();
95        returnsubmitButton.Text;
96      }
97      set
98      {
99        EnsureChildControls();
100        submitButton=value;
101      }
102    }
103
104
105    #endregion
106
107    #region组合控件呈现的样式
108    protectedoverrideHtmlTextWriterTagTagKey
109    {
110      get
111      {
112        returnHtmlTextWriterTag.Table;
113      }
114    }
115
116    protectedoverridevoidRenderContents(HtmlTextWriterwriter)
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值