其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难。
开发一个模板控件一般都继承CompositeControl,因为继承这个基类后,我们就省却了很多的麻烦。所以本章我们开
发的模板控件也继承于CompositeControl。大家应该还记得我们上章开发那个登录Login控件吧,如下:
     
以上就是我们之前开发的登录控件,现在我们来改造它。我们的现在的这个登录控件的输入用户名和密码的控件是
TextBox,我们有时候可能想把TextBox 换成DropdownList,或者其他的控件。也就说,我们想定制这个登录的控件。那
么,我们就要模板了。
首先来看看我们本章实现控件的最后效果:

 
     

大家看见没,这样我们就可以定制这个控件了。好了,我们来实现吧。
首先,我们让我们的模板控件继承上章的那个组合的Login控件:
class="cnblogs_code_copy">
 

 
然后,我们就声明我们的模板:
 

 
正如前面所说的,我们只是想定制两个输入信息的模板,大家可以根据需要,声明更多的模板。如,大家还可以
把显示的用户名的那些Label换成模板定制。
其实编写模板控件比编写一个组合控件更加的简单。大家稍后就可以体会到了。
好了,声明完了模板之后,我们的控件写了一大半了,还差一点。大家想想是什么???
对了,就是应用这些模板了。如下:
 

 
我想,大家对这个方法不陌生。因为我们之前的组合控件也是重写了这个方法。到这里,就写完了。
大家可能还有疑问,为什么这样重写 CreateChildControls()方法后,就会达到我们的效果?
下面,我就来将这个方法和之前的那个组合控件的 CreateChildControls()方法比较一下,也顺便讲下
模板的内幕。
先看组合控件的 CreateChildControls()方法,见下:
 

 
1.首先,在之前的组合控件中,我们是把那个TextBox,Label硬编码到了生成和初始化控件的方法
CreateChildControls()中。而在模板控件中,我们没有这样做,我们只是简单的调用了模板的一个方法:
InstantiateIn()。实际上,这个方法是个晚绑定。
为什么是晚绑定?先来看看下面:
                         
 
假设我们想用个下拉框来输入用户名,我们肯定要设计下拉框的属性,如 name,id,等等,当我们设置好
后,就形如这样了:
 

 
其实这样和在 CreateChildControls()中声明是一样的,形如:
 

 
其实模板控件的方法InstantiateIn()就是将之前的那个<ASp:dropdownlist....>代码转换为
DropDownList mylist=new DropDownList()...
不知道大家清楚,说到底就是个晚绑定!!!
到这里,模板控件完了,大家编译后,就后看到下面的控件:
               
然后,我们就在html代码开发声明:如下:
 

 
很多时候,我们不喜欢这样,因为我们更加喜欢图形化的设置,如下:

这样更加友好些。其实这也不难,只要加个设计器就可以了。
设计器是个类。在ASP.NET有很多的设计器,如ControlDesigner,CompositeControlDesigner.等等。
我们的设计器的一般都继承已有的设计器类。在这里我不多讲,大家需要的话,我专们用一章来讲。
 

 public class MyLoginDesigner : CompositeControlDesigner
public class MyLoginDesigner : CompositeControlDesigner {
    { public override void Initialize(IComponent component)
        public override void Initialize(IComponent component) {
        { base.Initialize(component);
            base.Initialize(component); SetViewFlags(ViewFlags.TemplateEditing, true);
            SetViewFlags(ViewFlags.TemplateEditing, true); }
        }
 public override string GetDesignTimeHtml()
        public override string GetDesignTimeHtml() {
        { TemplateLoginControl control = Component as TemplateLoginControl;
            TemplateLoginControl control = Component as TemplateLoginControl; if (control != null)
            if (control != null) {
            { if (control.LoginUserNameTemplate == null)
                if (control.LoginUserNameTemplate == null) {
                { return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
                    return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
 }
                }
 if (control.LoginUserPasswardTemplate == null)
                if (control.LoginUserPasswardTemplate == null) {
                { return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
                    return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板"); }
                } }
            } return base.GetDesignTimeHtml();
            return base.GetDesignTimeHtml(); }
        }
 private TemplateGroupCollection tempgc;
        private TemplateGroupCollection tempgc; public override TemplateGroupCollection TemplateGroups
        public override TemplateGroupCollection TemplateGroups {
        { get
            get {
            { if (tempgc == null)
                if (tempgc == null) {
                {
 tempgc = base.TemplateGroups;
                    tempgc = base.TemplateGroups;
 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
                    TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate"); loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
                    loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate", Component,"UserNameTemplate",false ));
                        Component,"UserNameTemplate",false )); tempgc.Add (loginUserNameTemplate );
                    tempgc.Add (loginUserNameTemplate );
 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
                    TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate"); loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
                    loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate", Component,"UserPasswardTemplate",false ));
                        Component,"UserPasswardTemplate",false )); tempgc.Add(loginPasswardNameTemplate);
                    tempgc.Add(loginPasswardNameTemplate); }
                } return tempgc;
                return tempgc; }
            } }
        } }
    }
 
然后在这样:
 

 
一切就OK了,写的有些催促,大家有问题我一定回复。
完整代码如下:
 

 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text; using System.Web;
using System.Web; using System.Web.UI;
using System.Web.UI; using System.Web.UI.WebControls;
using System.Web.UI.WebControls; using System.ComponentModel;
using System.ComponentModel; using System.Web.UI.Design;
using System.Web.UI.Design; using System.Web.UI.Design.WebControls ;
using System.Web.UI.Design.WebControls ; using System.Collections ;
using System.Collections ;



 namespace LoginControl
namespace LoginControl {
{ [Designer (typeof (MyLoginDesigner ))]
    [Designer (typeof (MyLoginDesigner ))] public class TemplateLoginControl:Login
    public class TemplateLoginControl:Login {
    { #region//声明模板
        #region//声明模板 private ITemplate loginUserNameTemplate;
        private ITemplate loginUserNameTemplate;
 [Browsable (false )]//我们不想在属性窗口中看见它
        [Browsable (false )]//我们不想在属性窗口中看见它 [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的,
        [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的, [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件
        [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件 public ITemplate LoginUserNameTemplate
        public ITemplate LoginUserNameTemplate {
        { get
            get {
            { return loginUserNameTemplate;
                return loginUserNameTemplate; }
            } set
            set {
            { loginUserNameTemplate = value;
                loginUserNameTemplate = value; }
            }
 }
        }
 private ITemplate loginUserPasswardTemplate;
        private ITemplate loginUserPasswardTemplate; [Browsable(false)]//我们不想在属性窗口中看见它
        [Browsable(false)]//我们不想在属性窗口中看见它 [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,
        [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的, [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件
        [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件 public ITemplate LoginUserPasswardTemplate
        public ITemplate LoginUserPasswardTemplate {
        { get
            get {
            { return loginUserPasswardTemplate;
                return loginUserPasswardTemplate; }
            } set
            set {
            { loginUserPasswardTemplate = value;
                loginUserPasswardTemplate = value; }
            } }
        } #endregion
        #endregion #region 重写创建控件的方法
        #region 重写创建控件的方法
 protected override void CreateChildControls()
        protected override void CreateChildControls() {
        { Controls.Clear();
            Controls.Clear(); if (loginUserNameTemplate != null)
            if (loginUserNameTemplate != null) loginUserNameTemplate.InstantiateIn(this);
                loginUserNameTemplate.InstantiateIn(this); else
            else base.CreateChildControls();
                base.CreateChildControls(); if(loginUserPasswardTemplate!=null )
            if(loginUserPasswardTemplate!=null ) loginUserPasswardTemplate .InstantiateIn(this);
                loginUserPasswardTemplate .InstantiateIn(this); else
            else base.CreateChildControls();
                base.CreateChildControls();
 ChildControlsCreated = true;
            ChildControlsCreated = true;
 
           
 }
        }
 #endregion
        #endregion


 }
    }
 public class MyLoginDesigner : CompositeControlDesigner
    public class MyLoginDesigner : CompositeControlDesigner {
    { public override void Initialize(IComponent component)
        public override void Initialize(IComponent component) {
        { base.Initialize(component);
            base.Initialize(component); SetViewFlags(ViewFlags.TemplateEditing, true);
            SetViewFlags(ViewFlags.TemplateEditing, true); }
        }
 public override string GetDesignTimeHtml()
        public override string GetDesignTimeHtml() {
        { TemplateLoginControl control = Component as TemplateLoginControl;
            TemplateLoginControl control = Component as TemplateLoginControl; if (control != null)
            if (control != null) {
            { if (control.LoginUserNameTemplate == null)
                if (control.LoginUserNameTemplate == null) {
                { return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
                    return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");
 }
                }
 if (control.LoginUserPasswardTemplate == null)
                if (control.LoginUserPasswardTemplate == null) {
                { return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
                    return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板"); }
                } }
            } return base.GetDesignTimeHtml();
            return base.GetDesignTimeHtml(); }
        }
 private TemplateGroupCollection tempgc;
        private TemplateGroupCollection tempgc; public override TemplateGroupCollection TemplateGroups
        public override TemplateGroupCollection TemplateGroups {
        { get
            get {
            { if (tempgc == null)
                if (tempgc == null) {
                {
 tempgc = base.TemplateGroups;
                    tempgc = base.TemplateGroups;
 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
                    TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate"); loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
                    loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate", Component,"UserNameTemplate",false ));
                        Component,"UserNameTemplate",false )); tempgc.Add (loginUserNameTemplate );
                    tempgc.Add (loginUserNameTemplate );
 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
                    TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate"); loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
                    loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate", Component,"UserPasswardTemplate",false ));
                        Component,"UserPasswardTemplate",false )); tempgc.Add(loginPasswardNameTemplate);
                    tempgc.Add(loginPasswardNameTemplate); }
                } return tempgc;
                return tempgc; }
            } }
        } }
    } }
}