第四章 组合控件开发CompositeControl
大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基类:Control,WebControl,还有一个就是今天要说的CompositeControl。 大家也许还记得,之前的开发的控件基本上都是我们自己从头到尾的写一些控件的标记,如<table.....>之类的,而且还有一个大的问题:我们为了使得我们的控件更加的好用,专业,我们还实现了大量的接口,和自己写很多的事件.这样开发控件的时间就加大了。其实我们可以利用ASP.NET中已经有的控件,经过我们包装,实现我们自定义控件。大家可能认为这和用户控件差不多的,但是继承CompositeConytol的控件的自定义控件的灵活性和复用行更好,而且还还添加样式。
还一个更加重要的就是我们不必要实现接口,比如,引发回传的IPostBackEventHandler接口,接受数据的IPostBackDataHandler接口。大家还记得我们之前开发控件中的的那个Button还要申明name为 this.UniqueID,现在我们都不需要了,因为我们要包装的那些服务器的控件,如TextBox,他们都已经实现了这些。
本章准备开发一个大家都熟知的Login登录控件。
大家先看看效果:
其实分析起来,这个控件是由一些已有的控件组合而成的,分别是:
两个Label,两个TextBox,和一个Button
下面我们就来开发:
首先,还是先继承CompositeControl;
1 publicclassLogin:CompositeControl
然后把就申明我们要组合的控件,如上所说的:
1 #region要组合的控件
2 LabellbUserName;
3 LabellbUserPassward;
4 TextBoxtxtUserName;
5 TextBoxtxtUserPassward;
6 ButtonsubmitButton;
7 #endregion
还一个更加重要的就是我们不必要实现接口,比如,引发回传的IPostBackEventHandler接口,接受数据的IPostBackDataHandler接口。大家还记得我们之前开发控件中的的那个Button还要申明name为 this.UniqueID,现在我们都不需要了,因为我们要包装的那些服务器的控件,如TextBox,他们都已经实现了这些。
本章准备开发一个大家都熟知的Login登录控件。
大家先看看效果:
其实分析起来,这个控件是由一些已有的控件组合而成的,分别是:
两个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
其实开发组合控件很简单,一般只要重写一个方法就可以了。这个方法就是来初始化并且整合那些已经申明了的小控件的。如下:
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的属性,还是看看效果图:
改前的图: 改后的图
就是说,我们想把子控件的属性如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 }
如果申明了ChildControlsCreated=true,那么这个方法就调用一次。
经过上面的步骤之后,其实我们的控件就已经开发完成了。
可能我们还想进一步的向我们ASP.NET的标准的Login控件靠拢.那么我们的控件还缺少什么?
属性,事件!!!
以前我们定义属性都是用的ViewState["..."],但是这里就不同了。因为我们的控件是有很多的小的控件组合起来的,比如,我们修改“用户名:”的那个Label,我们想改的是那个Label的属性,还是看看效果图:
改前的图: 改后的图
就是说,我们想把子控件的属性如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 }
大家可以根据需要显示更加多的属性。也可以自己定义一些属性,还是像以前那样,可以用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
我们的控件还差事件。我们在下篇将“事件的冒泡”。
顺便做个调查:大家想看开发控件的视频吗,我正在录制。
完整的代码:如下:
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
相信大家对上面的代码不陌生!!!
2.我们来定义一个委托:
1publicdelegatevoidValidateEventHandler(objectsender,ValidateEventArgsargs);
3.定义事件。
1 privatestaticreadonlyobjectValidateEventKey=newobject();
2 publiceventValidateEventHandlerValidateUserInfoChanged
3 {
4 add
5 {
6 Events.AddHandler(ValidateEventKey,value);
7 }
8 remove
9 {
10 Events.RemoveHandler(ValidateEventKey,value);
11 }
12 }
13
14 protectedvirtualvoidOnValidateChanged(ValidateEventArgsargs)
15 {
16 ValidateEventHandlerhandler=Events[ValidateEventKey]asValidateEventHandler;
17 if(handler!=null)
18 handler(this,args);
19 }
20
4.好了;准备都做好了,下面我们只要把这个事件冒泡成为Login的控件的就行了。其实很简单的。只要重写一个方法就行了。
如下:
1protectedoverrideboolOnBubbleEvent(objectsource,EventArgsargs)
2 {
3 boolhandled=false;
4
5 CommandEventArgsce=argsasCommandEventArgs;
6 if(ce!=null&&ce.CommandName=="Validate")
7 {
8 handled=true;
9 stringuserName=this.txtUserName.Text;
10 stringuserPassward=this.txtUserPassward.Text;
11
12 //把信息输入
13 ValidateEventArgsve=newValidateEventArgs(userName,userPassward);
14 OnValidateChanged(ve);
15 }
16 returnhandled;
17 }
2.我们来定义一个委托:
1publicdelegatevoidValidateEventHandler(objectsender,ValidateEventArgsargs);
3.定义事件。
1 privatestaticreadonlyobjectValidateEventKey=newobject();
2 publiceventValidateEventHandlerValidateUserInfoChanged
3 {
4 add
5 {
6 Events.AddHandler(ValidateEventKey,value);
7 }
8 remove
9 {
10 Events.RemoveHandler(ValidateEventKey,value);
11 }
12 }
13
14 protectedvirtualvoidOnValidateChanged(ValidateEventArgsargs)
15 {
16 ValidateEventHandlerhandler=Events[ValidateEventKey]asValidateEventHandler;
17 if(handler!=null)
18 handler(this,args);
19 }
20
4.好了;准备都做好了,下面我们只要把这个事件冒泡成为Login的控件的就行了。其实很简单的。只要重写一个方法就行了。
如下:
1protectedoverrideboolOnBubbleEvent(objectsource,EventArgsargs)
2 {
3 boolhandled=false;
4
5 CommandEventArgsce=argsasCommandEventArgs;
6 if(ce!=null&&ce.CommandName=="Validate")
7 {
8 handled=true;
9 stringuserName=this.txtUserName.Text;
10 stringuserPassward=this.txtUserPassward.Text;
11
12 //把信息输入
13 ValidateEventArgsve=newValidateEventArgs(userName,userPassward);
14 OnValidateChanged(ve);
15 }
16 returnhandled;
17 }
好了,完了,就这样了。
完整代码附上:
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4usingSystem.Web;
5usingSystem.Web.UI;
6usingSystem.Web.UI.WebControls;
7usingSystem.ComponentModel;
8
9namespaceLoginControl
10{
11 publicclassLogin:CompositeControl
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.Text =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.RenderEndTag();
128
129 writer.RenderEndTag();//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.RenderEndTag();
142
143 writer.RenderEndTag();//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.RenderEndTag();
154
155 writer.RenderEndTag();//tr的结束
156
157
158
159
160 }
161 #endregion
162
163 #region事件
164 privatestaticreadonlyobjectValidateEventKey=newobject();
165 publiceventValidateEventHandlerValidateUserInfoChanged
166 {
167 add
168 {
169 Events.AddHandler(ValidateEventKey,value);
170 }
171 remove
172 {
173 Events.RemoveHandler(ValidateEventKey,value);
174 }
175 }
176
177 protectedvirtualvoidOnValidateChanged(ValidateEventArgsargs)
178 {
179 ValidateEventHandlerhandler=Events[ValidateEventKey]asValidateEventHandler;
180 if(handler!=null)
181 handler(this,args);
182 }
183
184 #endregion
185
186 #region冒泡
187
188 protectedoverrideboolOnBubbleEvent(objectsource,EventArgsargs)
189 {
190 boolhandled=false;
191
192 CommandEventArgsce=argsasCommandEventArgs;
193 if(ce!=null&&ce.CommandName=="Validate")
194 {
195 handled=true;
196 stringuserName=this.txtUserName.Text;
197 stringuserPassward=this.txtUserPassward.Text;
198
199 //把信息输入
200 ValidateEventArgsve=newValidateEventArgs(userName,userPassward);
201 OnValidateChanged(ve);
202 }
203 returnhandled;
204 }
205 #endregion
206
207
208
209 }
210}
211
完整代码附上:
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4usingSystem.Web;
5usingSystem.Web.UI;
6usingSystem.Web.UI.WebControls;
7usingSystem.ComponentModel;
8
9namespaceLoginControl
10{
11 publicclassLogin:CompositeControl
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.Text =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.RenderEndTag();
128
129 writer.RenderEndTag();//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.RenderEndTag();
142
143 writer.RenderEndTag();//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.RenderEndTag();
154
155 writer.RenderEndTag();//tr的结束
156
157
158
159
160 }
161 #endregion
162
163 #region事件
164 privatestaticreadonlyobjectValidateEventKey=newobject();
165 publiceventValidateEventHandlerValidateUserInfoChanged
166 {
167 add
168 {
169 Events.AddHandler(ValidateEventKey,value);
170 }
171 remove
172 {
173 Events.RemoveHandler(ValidateEventKey,value);
174 }
175 }
176
177 protectedvirtualvoidOnValidateChanged(ValidateEventArgsargs)
178 {
179 ValidateEventHandlerhandler=Events[ValidateEventKey]asValidateEventHandler;
180 if(handler!=null)
181 handler(this,args);
182 }
183
184 #endregion
185
186 #region冒泡
187
188 protectedoverrideboolOnBubbleEvent(objectsource,EventArgsargs)
189 {
190 boolhandled=false;
191
192 CommandEventArgsce=argsasCommandEventArgs;
193 if(ce!=null&&ce.CommandName=="Validate")
194 {
195 handled=true;
196 stringuserName=this.txtUserName.Text;
197 stringuserPassward=this.txtUserPassward.Text;
198
199 //把信息输入
200 ValidateEventArgsve=newValidateEventArgs(userName,userPassward);
201 OnValidateChanged(ve);
202 }
203 returnhandled;
204 }
205 #endregion
206
207
208
209 }
210}
211
第五章 模板控件开发
大家好,我们今天来开发一个模板控件。
其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难。
开发一个模板控件一般都继承CompositeControl,因为继承这个基类后,我们就省却了很多的麻烦。所以本章我们开发的模板控件也继承于CompositeControl。大家应该还记得我们上章开发那个登录Login控件吧,如下:
以上就是我们之前开发的登录控件,现在我们来改造它。我们的现在的这个登录控件的输入用户名和密码的控件是TextBox,我们有时候可能想把TextBox 换成DropdownList,或者其他的控件。也就说,我们想定制这个登录的控件。那么,我们就要模板了。
首先来看看我们本章实现控件的最后效果:
大家看见没,这样我们就可以定制这个控件了。好了,我们来实现吧。
首先,我们让我们的模板控件继承上章的那个组合的Login控件:
Code
1 public class TemplateLoginControl:Login
其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难。
开发一个模板控件一般都继承CompositeControl,因为继承这个基类后,我们就省却了很多的麻烦。所以本章我们开发的模板控件也继承于CompositeControl。大家应该还记得我们上章开发那个登录Login控件吧,如下:
以上就是我们之前开发的登录控件,现在我们来改造它。我们的现在的这个登录控件的输入用户名和密码的控件是TextBox,我们有时候可能想把TextBox 换成DropdownList,或者其他的控件。也就说,我们想定制这个登录的控件。那么,我们就要模板了。
首先来看看我们本章实现控件的最后效果:
大家看见没,这样我们就可以定制这个控件了。好了,我们来实现吧。
首先,我们让我们的模板控件继承上章的那个组合的Login控件:
Code
1 public class TemplateLoginControl:Login
然后,我们就声明我们的模板:
Code
1 #region//声明模板
2 private ITemplate loginUserNameTemplate;
3
4 [Browsable (false )]//我们不想在属性窗口中看见它
5 [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的,
6 [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件
7 public ITemplate LoginUserNameTemplate
8 {
9 get
10 {
11 return loginUserNameTemplate;
12 }
13 set
14 {
15 loginUserNameTemplate = value;
16 }
17
18 }
19
20 private ITemplate loginUserPasswardTemplate;
21 [Browsable(false)]//我们不想在属性窗口中看见它
22 [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,
23 [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件
24 public ITemplate LoginUserPasswardTemplate
25 {
26 get
27 {
28 return loginUserPasswardTemplate;
29 }
30 set
31 {
32 loginUserPasswardTemplate = value;
33 }
34 }
35 #endregion
Code
1 #region//声明模板
2 private ITemplate loginUserNameTemplate;
3
4 [Browsable (false )]//我们不想在属性窗口中看见它
5 [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的,
6 [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件
7 public ITemplate LoginUserNameTemplate
8 {
9 get
10 {
11 return loginUserNameTemplate;
12 }
13 set
14 {
15 loginUserNameTemplate = value;
16 }
17
18 }
19
20 private ITemplate loginUserPasswardTemplate;
21 [Browsable(false)]//我们不想在属性窗口中看见它
22 [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,
23 [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件
24 public ITemplate LoginUserPasswardTemplate
25 {
26 get
27 {
28 return loginUserPasswardTemplate;
29 }
30 set
31 {
32 loginUserPasswardTemplate = value;
33 }
34 }
35 #endregion
正如前面所说的,我们只是想定制两个输入信息的模板,大家可以根据需要,声明更多的模板。如,大家还可以把显示的用户名的那些Label换成模板定制。
其实编写模板控件比编写一个组合控件更加的简单。大家稍后就可以体会到了。
好了,声明完了模板之后,我们的控件写了一大半了,还差一点。大家想想是什么???
对了,就是应用这些模板了。如下:
Code
1 protectedoverridevoidCreateChildControls()
2 {
3 Controls.Clear();
4 if(loginUserNameTemplate!=null)
5 loginUserNameTemplate.InstantiateIn(this);
6 else
7 base.CreateChildControls();
8 if(loginUserPasswardTemplate!=null)
9 loginUserPasswardTemplate.InstantiateIn(this);
10 else
11 base.CreateChildControls();
12
13 ChildControlsCreated=true;
14
15
16 }
我想,大家对这个方法不陌生。因为我们之前的组合控件也是重写了这个方法。到这里,就写完了。
大家可能还有疑问,为什么这样重写 CreateChildControls()方法后,就会达到我们的效果?
下面,我就来将这个方法和之前的那个组合控件的 CreateChildControls()方法比较一下,也顺便讲下模板的内幕。
先看组合控件的 CreateChildControls()方法,见下:
Code
1protectedoverridevoidCreateChildControls()
2 {
3 Controls.Clear();
4
5 //初始化控件lbUserName
6 lbUserName=newLabel();
7 lbUserName.Text="用户名:";
8 lbUserName.ID="lbUserName";
9 //把控件添加到我们的组合控件中
10 Controls.Add(lbUserName);
11
12 //初始化控件lbUserPassward
13 lbUserPassward=newLabel();
14 lbUserPassward.Text="密 码:";
15 lbUserPassward.ID="lbUserPassward";
16 Controls.Add(lbUserPassward);
17
18
19 txtUserName=newTextBox();
20 txtUserName.ID="txtUserName";
21 txtUserName.Width=Unit.Percentage(60);
22 Controls.Add(txtUserName);
23
24 txtUserPassward=newTextBox();
25 txtUserPassward.ID="txtUserPassward";
26 txtUserPassward.Width=Unit.Percentage(60);
27 Controls.Add(txtUserPassward);
28
29 submitButton =newButton();
30 submitButton.Text="提交";
31 submitButton.CommandName="Validate";
32 Controls.Add(submitButton);
33
34 ChildControlsCreated=true;
35 }
其实编写模板控件比编写一个组合控件更加的简单。大家稍后就可以体会到了。
好了,声明完了模板之后,我们的控件写了一大半了,还差一点。大家想想是什么???
对了,就是应用这些模板了。如下:
Code
1 protectedoverridevoidCreateChildControls()
2 {
3 Controls.Clear();
4 if(loginUserNameTemplate!=null)
5 loginUserNameTemplate.InstantiateIn(this);
6 else
7 base.CreateChildControls();
8 if(loginUserPasswardTemplate!=null)
9 loginUserPasswardTemplate.InstantiateIn(this);
10 else
11 base.CreateChildControls();
12
13 ChildControlsCreated=true;
14
15
16 }
我想,大家对这个方法不陌生。因为我们之前的组合控件也是重写了这个方法。到这里,就写完了。
大家可能还有疑问,为什么这样重写 CreateChildControls()方法后,就会达到我们的效果?
下面,我就来将这个方法和之前的那个组合控件的 CreateChildControls()方法比较一下,也顺便讲下模板的内幕。
先看组合控件的 CreateChildControls()方法,见下:
Code
1protectedoverridevoidCreateChildControls()
2 {
3 Controls.Clear();
4
5 //初始化控件lbUserName
6 lbUserName=newLabel();
7 lbUserName.Text="用户名:";
8 lbUserName.ID="lbUserName";
9 //把控件添加到我们的组合控件中
10 Controls.Add(lbUserName);
11
12 //初始化控件lbUserPassward
13 lbUserPassward=newLabel();
14 lbUserPassward.Text="密 码:";
15 lbUserPassward.ID="lbUserPassward";
16 Controls.Add(lbUserPassward);
17
18
19 txtUserName=newTextBox();
20 txtUserName.ID="txtUserName";
21 txtUserName.Width=Unit.Percentage(60);
22 Controls.Add(txtUserName);
23
24 txtUserPassward=newTextBox();
25 txtUserPassward.ID="txtUserPassward";
26 txtUserPassward.Width=Unit.Percentage(60);
27 Controls.Add(txtUserPassward);
28
29 submitButton =newButton();
30 submitButton.Text="提交";
31 submitButton.CommandName="Validate";
32 Controls.Add(submitButton);
33
34 ChildControlsCreated=true;
35 }
1.首先,在之前的组合控件中,我们是把那个TextBox,Label硬编码到了生成和初始化控件的方法CreateChildControls()中。而在模板控件中,我们没有这样做,我们只是简单的调用了模板的一个方法: InstantiateIn()。实际上,这个方法是个晚绑定。
为什么是晚绑定?先来看看下面:
假设我们想用个下拉框来输入用户名,我们肯定要设计下拉框的属性,如 name,id,等等,当我们设置好后,就形如这样了:
Code
1<asp:DropDownListID="mylist"runat="server"BackColor="red"></asp:DropDownList>
其实这样和在CreateChildControls()中声明是一样的,形如:
Code
1 DropDownListmylist=newDropDownList();
2 mylist.ID="mylist";
3 mylist.Items=newListItemCollection();
4 Controls.Add(mylist);
5
其实模板控件的方法InstantiateIn()就是将之前的那个<ASp:dropdownlist....>代码转换为
DropDownList mylist=new DropDownList()...
不知道大家清楚,说到底就是个晚绑定!!!
到这里,模板控件完了,大家编译后,就后看到下面的控件:
然后,我们就在html代码开发声明:如下:
为什么是晚绑定?先来看看下面:
假设我们想用个下拉框来输入用户名,我们肯定要设计下拉框的属性,如 name,id,等等,当我们设置好后,就形如这样了:
Code
1<asp:DropDownListID="mylist"runat="server"BackColor="red"></asp:DropDownList>
其实这样和在CreateChildControls()中声明是一样的,形如:
Code
1 DropDownListmylist=newDropDownList();
2 mylist.ID="mylist";
3 mylist.Items=newListItemCollection();
4 Controls.Add(mylist);
5
其实模板控件的方法InstantiateIn()就是将之前的那个<ASp:dropdownlist....>代码转换为
DropDownList mylist=new DropDownList()...
不知道大家清楚,说到底就是个晚绑定!!!
到这里,模板控件完了,大家编译后,就后看到下面的控件:
然后,我们就在html代码开发声明:如下:
Code
1 <cc1:TemplateLoginCrunat="server">
2 <LoginUserNameTemplate>
3
4 </LoginUserNameTemplate>
5 <LoginUserPasswardTemplate>
6
7 </LoginUserPasswardTemplate>
8 </cc1:TemplateLoginControl>
9
很多时候,我们不喜欢这样,因为我们更加喜欢图形化的设置,如下:
这样更加友好些。其实这也不难,只要加个设计器就可以了。
设计器是个类。在ASP.NET有很多的设计器,如ControlDesigner,CompositeControlDesigner.等等。
我们的设计器的一般都继承已有的设计器类。在这里我不多讲,大家需要的话,我专们用一章来讲。
Code
1public class MyLoginDesigner : CompositeControlDesigner
2 {
3 public override void Initialize(IComponent component)
4 {
5 base.Initialize(component);
6 SetViewFlags(ViewFlags.TemplateEditing, true);
7 }
8
9 public override string GetDesignTimeHtml()
10 {
11 TemplateLoginControl control = Component as TemplateLoginControl;
12 if (control != null)
13 {
14 if (control.LoginUserNameTemplate == null)
15 {
16 return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
17
18 }
19
20 if (control.LoginUserPasswardTemplate == null)
21 {
22 return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
23 }
24 }
25 return base.GetDesignTimeHtml();
26 }
27
28 private TemplateGroupCollection tempgc;
29 public override TemplateGroupCollection TemplateGroups
30 {
31 get
32 {
33 if (tempgc == null)
34 {
35
36 tempgc = base.TemplateGroups;
37
38 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
39 loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
40 Component,"UserNameTemplate",false ));
41 tempgc.Add (loginUserNameTemplate );
42
43 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
44 loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
45 Component,"UserPasswardTemplate",false ));
46 tempgc.Add(loginPasswardNameTemplate);
47 }
48 return tempgc;
49 }
50 }
51 }
1 <cc1:TemplateLoginCrunat="server">
2 <LoginUserNameTemplate>
3
4 </LoginUserNameTemplate>
5 <LoginUserPasswardTemplate>
6
7 </LoginUserPasswardTemplate>
8 </cc1:TemplateLoginControl>
9
很多时候,我们不喜欢这样,因为我们更加喜欢图形化的设置,如下:
这样更加友好些。其实这也不难,只要加个设计器就可以了。
设计器是个类。在ASP.NET有很多的设计器,如ControlDesigner,CompositeControlDesigner.等等。
我们的设计器的一般都继承已有的设计器类。在这里我不多讲,大家需要的话,我专们用一章来讲。
Code
1public class MyLoginDesigner : CompositeControlDesigner
2 {
3 public override void Initialize(IComponent component)
4 {
5 base.Initialize(component);
6 SetViewFlags(ViewFlags.TemplateEditing, true);
7 }
8
9 public override string GetDesignTimeHtml()
10 {
11 TemplateLoginControl control = Component as TemplateLoginControl;
12 if (control != null)
13 {
14 if (control.LoginUserNameTemplate == null)
15 {
16 return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
17
18 }
19
20 if (control.LoginUserPasswardTemplate == null)
21 {
22 return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
23 }
24 }
25 return base.GetDesignTimeHtml();
26 }
27
28 private TemplateGroupCollection tempgc;
29 public override TemplateGroupCollection TemplateGroups
30 {
31 get
32 {
33 if (tempgc == null)
34 {
35
36 tempgc = base.TemplateGroups;
37
38 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
39 loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
40 Component,"UserNameTemplate",false ));
41 tempgc.Add (loginUserNameTemplate );
42
43 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
44 loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
45 Component,"UserPasswardTemplate",false ));
46 tempgc.Add(loginPasswardNameTemplate);
47 }
48 return tempgc;
49 }
50 }
51 }
然后在这样: Code
1 [Designer (typeof (MyLoginDesigner ))]
2 public class TemplateLoginControl:Login
一切就OK了,写的有些催促,大家有问题我一定回复。
完整代码如下:
Code
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Web;
5using System.Web.UI;
6using System.Web.UI.WebControls;
7using System.ComponentModel;
8using System.Web.UI.Design;
9using System.Web.UI.Design.WebControls ;
10using System.Collections ;
11
12
13
14
15namespace LoginControl
16{
17 [Designer (typeof (MyLoginDesigner ))]
18 public class TemplateLoginControl:Login
19 {
20 //声明模板#region//声明模板
21 private ITemplate loginUserNameTemplate;
22
23 [Browsable (false )]//我们不想在属性窗口中看见它
24 [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的,
25 [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件
26 public ITemplate LoginUserNameTemplate
27 {
28 get
29 {
30 return loginUserNameTemplate;
31 }
32 set
33 {
34 loginUserNameTemplate = value;
35 }
36
37 }
38
39 private ITemplate loginUserPasswardTemplate;
40 [Browsable(false)]//我们不想在属性窗口中看见它
41 [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,
42 [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件
43 public ITemplate LoginUserPasswardTemplate
44 {
45 get
46 {
47 return loginUserPasswardTemplate;
48 }
49 set
50 {
51 loginUserPasswardTemplate = value;
52 }
53 }
54 #endregion
55 重写创建控件的方法#region 重写创建控件的方法
56
57 protected override void CreateChildControls()
58 {
59 Controls.Clear();
60 if (loginUserNameTemplate != null)
61 loginUserNameTemplate.InstantiateIn(this);
62 else
63 base.CreateChildControls();
64 if(loginUserPasswardTemplate!=null )
65 loginUserPasswardTemplate .InstantiateIn(this);
66 else
67 base.CreateChildControls();
68
69 ChildControlsCreated = true;
70
71
72
73 }
74
75 #endregion
76
77
78
79 }
80
81 public class MyLoginDesigner : CompositeControlDesigner
82 {
83 public override void Initialize(IComponent component)
84 {
85 base.Initialize(component);
86 SetViewFlags(ViewFlags.TemplateEditing, true);
87 }
88
89 public override string GetDesignTimeHtml()
90 {
91 TemplateLoginControl control = Component as TemplateLoginControl;
92 if (control != null)
93 {
94 if (control.LoginUserNameTemplate == null)
95 {
96 return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
97
98 }
99
100 if (control.LoginUserPasswardTemplate == null)
101 {
102 return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
103 }
104 }
105 return base.GetDesignTimeHtml();
106 }
107
108 private TemplateGroupCollection tempgc;
109 public override TemplateGroupCollection TemplateGroups
110 {
111 get
112 {
113 if (tempgc == null)
114 {
115
116 tempgc = base.TemplateGroups;
117
118 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
119 loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
120 Component,"UserNameTemplate",false ));
121 tempgc.Add (loginUserNameTemplate );
122
123 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
124 loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
125 Component,"UserPasswardTemplate",false ));
126 tempgc.Add(loginPasswardNameTemplate);
127 }
128 return tempgc;
129 }
130 }
131 }
132}
133
1 [Designer (typeof (MyLoginDesigner ))]
2 public class TemplateLoginControl:Login
一切就OK了,写的有些催促,大家有问题我一定回复。
完整代码如下:
Code
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Web;
5using System.Web.UI;
6using System.Web.UI.WebControls;
7using System.ComponentModel;
8using System.Web.UI.Design;
9using System.Web.UI.Design.WebControls ;
10using System.Collections ;
11
12
13
14
15namespace LoginControl
16{
17 [Designer (typeof (MyLoginDesigner ))]
18 public class TemplateLoginControl:Login
19 {
20 //声明模板#region//声明模板
21 private ITemplate loginUserNameTemplate;
22
23 [Browsable (false )]//我们不想在属性窗口中看见它
24 [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的,
25 [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件
26 public ITemplate LoginUserNameTemplate
27 {
28 get
29 {
30 return loginUserNameTemplate;
31 }
32 set
33 {
34 loginUserNameTemplate = value;
35 }
36
37 }
38
39 private ITemplate loginUserPasswardTemplate;
40 [Browsable(false)]//我们不想在属性窗口中看见它
41 [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,
42 [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件
43 public ITemplate LoginUserPasswardTemplate
44 {
45 get
46 {
47 return loginUserPasswardTemplate;
48 }
49 set
50 {
51 loginUserPasswardTemplate = value;
52 }
53 }
54 #endregion
55 重写创建控件的方法#region 重写创建控件的方法
56
57 protected override void CreateChildControls()
58 {
59 Controls.Clear();
60 if (loginUserNameTemplate != null)
61 loginUserNameTemplate.InstantiateIn(this);
62 else
63 base.CreateChildControls();
64 if(loginUserPasswardTemplate!=null )
65 loginUserPasswardTemplate .InstantiateIn(this);
66 else
67 base.CreateChildControls();
68
69 ChildControlsCreated = true;
70
71
72
73 }
74
75 #endregion
76
77
78
79 }
80
81 public class MyLoginDesigner : CompositeControlDesigner
82 {
83 public override void Initialize(IComponent component)
84 {
85 base.Initialize(component);
86 SetViewFlags(ViewFlags.TemplateEditing, true);
87 }
88
89 public override string GetDesignTimeHtml()
90 {
91 TemplateLoginControl control = Component as TemplateLoginControl;
92 if (control != null)
93 {
94 if (control.LoginUserNameTemplate == null)
95 {
96 return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
97
98 }
99
100 if (control.LoginUserPasswardTemplate == null)
101 {
102 return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
103 }
104 }
105 return base.GetDesignTimeHtml();
106 }
107
108 private TemplateGroupCollection tempgc;
109 public override TemplateGroupCollection TemplateGroups
110 {
111 get
112 {
113 if (tempgc == null)
114 {
115
116 tempgc = base.TemplateGroups;
117
118 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
119 loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
120 Component,"UserNameTemplate",false ));
121 tempgc.Add (loginUserNameTemplate );
122
123 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
124 loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
125 Component,"UserPasswardTemplate",false ));
126 tempgc.Add(loginPasswardNameTemplate);
127 }
128 return tempgc;
129 }
130 }
131 }
132}
133