ASP.NET自定义控件组件开发(三)

来源:互联网 发布:在线代码编辑器java 编辑:程序博客网 时间:2024/05/29 09:13

第四章 组合控件开发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
 把控件申明了之后只要初始化,并且将这些控件整合成我们的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的属性,还是看看效果图:
  改前的图:                            改后的图
 
  就是说,我们想把子控件的属性如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
 相信大家对上面的代码不陌生!!!

  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

第五章 模板控件开发

  大家好,我们今天来开发一个模板控件。
  其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难。
  开发一个模板控件一般都继承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
  正如前面所说的,我们只是想定制两个输入信息的模板,大家可以根据需要,声明更多的模板。如,大家还可以把显示的用户名的那些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    }
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代码开发声明:如下:
  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  }
然后在这样:  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
原创粉丝点击