ASP.NET自定义控件组件开发 第五章 模板控件开发
原文:ASP.NET自定义控件组件开发 第五章 模板控件开发
第五章 模板控件开发
系列文章链接:
ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件
ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇
ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇
ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡
大家好,我们今天来开发一个模板控件。
其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难。
开发一个模板控件一般都继承CompositeControl,因为继承这个基类后,我们就省却了很多的麻烦。所以本章我们开
发的模板控件也继承于CompositeControl。大家应该还记得我们上章开发那个登录Login控件吧,如下:
以上就是我们之前开发的登录控件,现在我们来改造它。我们的现在的这个登录控件的输入用户名和密码的控件是
TextBox,我们有时候可能想把TextBox 换成DropdownList,或者其他的控件。也就说,我们想定制这个登录的控件。那
么,我们就要模板了。
首先来看看我们本章实现控件的最后效果:
大家看见没,这样我们就可以定制这个控件了。好了,我们来实现吧。
首先,我们让我们的模板控件继承上章的那个组合的Login控件:
Code
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
{
return loginUserNameTemplate;
}
set
{
loginUserNameTemplate = value;
}
}
private ITemplate loginUserPasswardTemplate;
[Browsable(false)]//我们不想在属性窗口中看见它
[TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,
[PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件
public ITemplate LoginUserPasswardTemplate
{
get
{
return loginUserPasswardTemplate;
}
set
{
loginUserPasswardTemplate = value;
}
}
#endregion
正如前面所说的,我们只是想定制两个输入信息的模板,大家可以根据需要,声明更多的模板。如,大家还可以
把显示的用户名的那些Label换成模板定制。
其实编写模板控件比编写一个组合控件更加的简单。大家稍后就可以体会到了。
好了,声明完了模板之后,我们的控件写了一大半了,还差一点。大家想想是什么???
对了,就是应用这些模板了。如下:
Code
1 protected override void CreateChildControls()
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);
else
base.CreateChildControls();
ChildControlsCreated = true;
}
我想,大家对这个方法不陌生。因为我们之前的组合控件也是重写了这个方法。到这里,就写完了。
大家可能还有疑问,为什么这样重写 CreateChildControls()方法后,就会达到我们的效果?
下面,我就来将这个方法和之前的那个组合控件的 CreateChildControls()方法比较一下,也顺便讲下
模板的内幕。
先看组合控件的 CreateChildControls()方法,见下:
Code
1 protected override void CreateChildControls()
2 {
3 Controls.Clear();
4
5 //初始化控件lbUserName
6 lbUserName = new Label();
7 lbUserName.Text = "用户名:";
8 lbUserName.ID = "lbUserName";
9 //把控件添加到我们的组合控件中
Controls.Add(lbUserName);
//初始化控件lbUserPassward
lbUserPassward = new Label();
lbUserPassward.Text = "密 码:";
lbUserPassward.ID = "lbUserPassward";
Controls.Add(lbUserPassward);
txtUserName = new TextBox();
txtUserName.ID = "txtUserName";
txtUserName.Width = Unit.Percentage();
Controls.Add(txtUserName);
txtUserPassward = new TextBox();
txtUserPassward.ID = "txtUserPassward";
txtUserPassward.Width = Unit.Percentage();
Controls.Add(txtUserPassward);
submitButton = new Button();
submitButton.Text = "提交";
submitButton.CommandName = "Validate";
Controls.Add(submitButton);
ChildControlsCreated = true;
}
1.首先,在之前的组合控件中,我们是把那个TextBox,Label硬编码到了生成和初始化控件的方法
CreateChildControls()中。而在模板控件中,我们没有这样做,我们只是简单的调用了模板的一个方法:
InstantiateIn()。实际上,这个方法是个晚绑定。
为什么是晚绑定?先来看看下面:
假设我们想用个下拉框来输入用户名,我们肯定要设计下拉框的属性,如 name,id,等等,当我们设置好
后,就形如这样了:
Code
<asp:DropDownList ID="mylist" runat="server" BackColor ="red" ></asp:DropDownList>
其实这样和在 CreateChildControls()中声明是一样的,形如:
Code
DropDownList mylist = new DropDownList();
mylist.ID = "mylist";
mylist.Items = new ListItemCollection();
Controls.Add(mylist);
其实模板控件的方法InstantiateIn()就是将之前的那个<ASp:dropdownlist....>代码转换为
DropDownList mylist=new DropDownList()...
不知道大家清楚,说到底就是个晚绑定!!!
到这里,模板控件完了,大家编译后,就后看到下面的控件:
然后,我们就在html代码开发声明:如下:
Code
<cc1:TemplateLoginControl ID="TemplateLoginControl1" runat="server">
<LoginUserNameTemplate >
</LoginUserNameTemplate>
<LoginUserPasswardTemplate>
</LoginUserPasswardTemplate>
</cc1:TemplateLoginControl>
很多时候,我们不喜欢这样,因为我们更加喜欢图形化的设置,如下:
这样更加友好些。其实这也不难,只要加个设计器就可以了。
设计器是个类。在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()
{
TemplateLoginControl control = Component as TemplateLoginControl;
if (control != null)
{
if (control.LoginUserNameTemplate == null)
{
return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板"); } if (control.LoginUserPasswardTemplate == null)
{
return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
}
}
return base.GetDesignTimeHtml();
} private TemplateGroupCollection tempgc;
public override TemplateGroupCollection TemplateGroups
{
get
{
if (tempgc == null)
{ tempgc = base.TemplateGroups; TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
Component,"UserNameTemplate",false ));
tempgc.Add (loginUserNameTemplate ); TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
Component,"UserPasswardTemplate",false ));
tempgc.Add(loginPasswardNameTemplate);
}
return tempgc;
}
}
}
然后在这样:
Code
[Designer (typeof (MyLoginDesigner ))]
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
if (control.LoginUserPasswardTemplate == null)
{
return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
}
}
return base.GetDesignTimeHtml();
} private TemplateGroupCollection tempgc;
public override TemplateGroupCollection TemplateGroups
{
get
{
if (tempgc == null)
{ tempgc = base.TemplateGroups; TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
Component,"UserNameTemplate",false ));
tempgc.Add (loginUserNameTemplate ); TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
Component,"UserPasswardTemplate",false ));
tempgc.Add(loginPasswardNameTemplate);
}
return tempgc;
}
}
}
}
.
ASP.NET自定义控件组件开发 第五章 模板控件开发的更多相关文章
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl 后篇 --事件冒泡 系列文章链接: 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 ...
- 安全控件开发原理分析 支付宝安全控件开发 C++
浏览器安全控件是如果支付宝一样结合web程序密码数据安全处理的程序,采用C++语言开发 通常的安全控件分为两种,一种是指支持IE内核的浏览器,一种支持所有内核的浏览器,支付宝采用的是支持所有内核的浏览 ...
- WP8.1学习系列(第五章)——中心控件Hub或透视控件Pivot交互UX
具有主页菜单(中心或透视控件)的中心应用中心 你可能要设计包含许多功能的应用.当你看着这些功能时,可能会决定将它们整理到独立的区域中.这些区域最终会成为用户要访问的应用的独立部分.你需要设计一个简便的 ...
- 【Android】14.0 UI开发(五)——列表控件RecyclerView的瀑布布局排列实现
1.0 列表控件RecyclerView的瀑布布局排列实现,关键词StaggeredGridLayoutManager LinearLayoutManager 实现顺序布局 GridLayoutMan ...
- 【WPF学习】第二十五章 日期控件
WPF包含两个日期控件:Calender和DatePicker.这两个控件都被设计为允许用户选择日期. Calendar控件显示日期,在与Windows操作系统中看到的日历(例如,当配置系统日期时看到 ...
随机推荐
- no copy constructor available or copy constructor is declared 'explicit'
今天新写了一个类.然后对这个类使用STL中的vector,碰到错误: no copy constructor available or copy constructor is declared 'ex ...
- Android Bitmap 载入与像素操作
Android Bitmap 载入与像素操作 一:载入与像素读写 在Android SDK中,图像的像素读写能够通过getPixel与setPixel两个Bitmap的API实现. Bitmap AP ...
- jconsole线程面板中的阻塞总数和等待总数(转)
阻塞总数 Blocked count is the total number of times that the thread blocked to enter or reenter a monito ...
- 所有城市list每次从页面花1段时间抽取后写入到数组,
所有城市list每次从页面花1段时间抽取后写入到数组,
- cocos2d-x 精灵的创建和基本使用
在cocos2d-x中.精灵能够说是一个最重要的组成元素,它代表游戏中一个最小的可见单位.同一时候也是CCNode一个最为灵活的子类,由于它能够通过装载一个平面纹理,从而具有丰富的表现力. 在进一步说 ...
- 普通的年轻状态机,纯C语言
我们第一次接触到了状态机.在数字电路课程.计数器.串行奇偶校验.考了1连续报错电路 等待,两者都需要一个状态机模型.电路实现这些功能,与状态机的状态转移图.状态转移表是等价. 后.然后,我们联系了状态 ...
- UML序列图总结(转)
序列图主要用于展示对象之间交互的顺序. 序列图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色用一条虚线 ...
- CodeBlocks暴力恢复默认设置
昨天,我不知道怎么去CodeBlocks干净的界面使自己都不知道怎么走.然后找到默认设置恢复方法,找不到.然后,我用了一个恢复方法暴力,卸载重装,有一点须要注意.卸载后CodeBlocks的配置文件还 ...
- ASP.NET 应用程序生命周期
1.请求到达IIS服务器,IIS根据文件后缀找到对应的ISAPI(Internet Server API)扩展来处理,这个配置可在网站属性里的“根目录”选项卡中的“配置”里看到.可以看到,ashx.a ...
- Linux date -s(转)
修改linux的时间可以使用date指令 修改日期: 时间设定成2009年5月10日的命令如下: #date -s 05/10/2009 修改时间: 将系统时间设定成上午10点18分0秒的命令如下. ...