ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
第四章 组合控件开发CompositeControl
大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基
类:Control,WebControl,还有一个就是今天要说的CompositeControl。
系列文章链接:
ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件
ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇
ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇
ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡
大家也许还记得,之前的开发的控件基本上都是我们自己从头到尾的写一些控件的标记,如<table.....>之类的,
而且还有一个大的问题:我们为了使得我们的控件更加的好用,专业,我们还实现了大量的接口,和自己写很多的事件.这样
开发控件的时间就加大了。其实我们可以利用ASP.NET中已经有的控件,经过我们包装,实现我们自定义控件。大家可能认
为这和用户控件差不多的,但是继承CompositeConytol的控件的自定义控件的灵活性和复用行更好,而且还还添加样式。
还一个更加重要的就是我们不必要实现接口,比如,引发回传的IPostBackEventHandler接口,接受数据的
IPostBackDataHandler接口。大家还记得我们之前开发控件中的的那个Button还要申明name为 this.UniqueID ,
现在我们都不需要了,因为我们要包装的那些服务器的控件,如TextBox,他们都已经实现了这些。
本章准备开发一个大家都熟知的Login登录控件。
大家先看看效果:
其实分析起来,这个控件是由一些已有的控件组合而成的,分别是:
两个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的属性,还是看看效果图:
改前的图: 改后的图
就是说,我们想把子控件的属性如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的更多相关文章
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl 后篇 --事件冒泡 系列文章链接: ASP.NET ...
- ASP.NET自定义控件组件开发 第五章 模板控件开发
原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...
- ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇
原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...
- ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇
原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...
- 『Asp.Net 组件』第一个 Asp.Net 服务器组件:自己的文本框控件
代码: using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace DemoWebControl ...
- Andriod 自定义控件之创建可以复用的组合控件
前面已学习了一种自定义控件的实现,是Andriod 自定义控件之音频条,还没学习的同学可以学习下,学习了的同学也要去温习下,一定要自己完全的掌握了,再继续学习,贪多嚼不烂可不是好的学习方法,我们争取学 ...
- Android开发学习笔记-自定义组合控件的过程
自定义组合控件的过程 1.自定义一个View 一般来说,继承相对布局,或者线性布局 ViewGroup:2.实现父类的构造方法.一般来说,需要在构造方法里初始化自定义的布局文件:3.根据一些需要或者需 ...
- 安全控件开发原理分析 支付宝安全控件开发 C++
浏览器安全控件是如果支付宝一样结合web程序密码数据安全处理的程序,采用C++语言开发 通常的安全控件分为两种,一种是指支持IE内核的浏览器,一种支持所有内核的浏览器,支付宝采用的是支持所有内核的浏览 ...
- 【Android】13.0 UI开发(四)——列表控件RecyclerView的横向布局排列实现
1.0 新建项目,由于ListView的局限性,RecyclerView是一种很好取代ListView的控件,可以灵活实现多种布局. 2.0 新建项目RecyclerviewTest,目录如下: 3. ...
随机推荐
- [置顶] hdu 4699 2个栈维护 or 伸展树
hdu 4699 Editor 题意:对一个数列进行操作,光标位置后面插入一个权值为x的数,删除光标前的那个数,光标左移一位,光标右移一位,求到k位置的最大的前缀和.. 注意这里的k是在光标之前的, ...
- 使用Google Roads API抓取道路信息(java实现)
Google Roads API提供了强大的道路获取接口,用户仅仅需调用对应的API就能够获取对应区域的道路坐标以及道路的限速信息. 详细的调用方法例如以下: https://roads.google ...
- Unity3D中的Update, FixedUpdate, LateUpdate的区别
MonoBehaviour.Update 更新 当MonoBehaviour启用时,其Update在每一帧被调用. MonoBehaviour.FixedUpdate 固定更新 当MonoBehavi ...
- MYSQL中的字符串连接符
update `table` set nsdf = concat('a','b') where id=137
- javascript UniqueID属性
在Web页中的每一个HTML元素都一个ID属性,ID作为其标示,在我们的普通理解中它应该是unique的.但是HTML元素的ID属性是可写的,这就造成了我们非常可能人为的使ID的反复.按么假设 ...
- 作为一个.net程序猿,需要掌握这些有点前途的人才,一些开发---Shinepans
1.基础 C#基础 参考书目: <c#入门经典> <ASP.NET揭秘> IIS HTML ...
- Eclipse关闭检查
有没有发现每次操作Eclipse过后,都会有build Workspace的操作一直在后台执行,JS校验一直validate,非常卡非常受不了有木有? 有木有?以下是我个人成功的步骤,曾经试过非常多次 ...
- hdu1506(dp减少重复计算)
可以算出以第i个值为高度的矩形可以向左延伸left[i],向右延伸right[i]的长度 那么答案便是 (left[i] + right[i] + 1) * a[i] 的最大值 关键left[i] 和 ...
- Android源代码同步脚本(增加设置线程参数)
#!/bin/sh #Filename: repo_sync.sh count= ret= ] do #输入参数1,用作同步的线程数 #如果什么参数都不输入,默认线程为4 #usage: ./repo ...
- Codeforces Round #256 (Div. 2) A. Rewards
A. Rewards time limit per test 1 second memory limit per test 256 megabytes input standard input out ...