Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1150836
  • 博文数量: 141
  • 博客积分: 3161
  • 博客等级: 中校
  • 技术积分: 3011
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-27 14:53
文章存档

2012年(28)

2011年(113)

分类: 系统运维

2011-09-29 12:16:09

    大家好,我们今天来开发一个模板控件。

     

    其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难。

 

    开发一个模板控件一般都继承CompositeControl,因为继承这个基类后,我们就省却了很多的麻烦。所以本章我们开发的模板控件也继承于CompositeControl。大家应该还记得我们上章开发那个登录Login控件吧,如下:

     

 

    以上就是我们之前开发的登录控件,现在我们来改造它。我们的现在的这个登录控件的输入用户名和密码的控件是TextBox,我们有时候可能想把TextBox 换成DropdownList,或者其他的控件。也就说,我们想定制这个登录的控件。那么,我们就要模板了。

 

    首先来看看我们本章实现控件的最后效果:

     

 

    大家看见没,这样我们就可以定制这个控件了。好了,我们来实现吧。

    首先,我们让我们的模板控件继承上章的那个组合的Login控件: 

  1. public class TemplateLoginControl:Login

 

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

 
  1. #region//声明模板

  2.         private ITemplate loginUserNameTemplate;

  3.         [Browsable(false)]//我们不想在属性窗口中看见它

  4.         [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,

  5.         [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件

  6.         public ITemplate LoginUserNameTemplate
  7.         {
  8.             get
  9.             {
  10.                 return loginUserNameTemplate;
  11.             }
  12.             set
  13.             {
  14.                 loginUserNameTemplate = value;
  15.             }

  16.         }

  17.         private ITemplate loginUserPasswardTemplate;
  18.         [Browsable(false)]//我们不想在属性窗口中看见它

  19.         [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,

  20.         [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件

  21.         public ITemplate LoginUserPasswardTemplate
  22.         {
  23.             get
  24.             {
  25.                 return loginUserPasswardTemplate;
  26.             }
  27.             set
  28.             {
  29.                 loginUserPasswardTemplate = value;
  30.             }
  31.         }
  32.         #endregion

    正如前面所说的,我们只是想定制两个输入信息的模板,大家可以根据需要,声明更多的模板。如,大家还可以把显示的用户名的那些Label换成模板定制。

 

    其实编写模板控件比编写一个组合控件更加的简单。大家稍后就可以体会到了。

     好了,声明完了模板之后,我们的控件写了一大半了,还差一点。大家想想是什么???

    对了,就是应用这些模板了。如下:

 

  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);
  10.             else
  11.                 base.CreateChildControls();

  12.             ChildControlsCreated = true;


  13.         }

 

    我想,大家对这个方法不陌生。因为我们之前的组合控件也是重写了这个方法。到这里,就写完了。

          

    大家可能还有疑问,为什么这样重写 CreateChildControls()方法后,就会达到我们的效果?

 

    下面,我就来将这个方法和之前的那个组合控件的 CreateChildControls()方法比较一下,也顺便讲下模板的内幕。

 

    先看组合控件的 CreateChildControls()方法,见下:

 

  1. protected override void CreateChildControls()
  2.         {
  3.             Controls.Clear();

  4.             //初始化控件lbUserName

  5.             lbUserName = new Label();
  6.             lbUserName.Text = "用户名:";
  7.             lbUserName.ID = "lbUserName";
  8.             //把控件添加到我们的组合控件中

  9.             Controls.Add(lbUserName);

  10.             //初始化控件lbUserPassward

  11.             lbUserPassward = new Label();
  12.             lbUserPassward.Text = "密 码:";
  13.             lbUserPassward.ID = "lbUserPassward";
  14.             Controls.Add(lbUserPassward);


  15.             txtUserName = new TextBox();
  16.             txtUserName.ID = "txtUserName";
  17.             txtUserName.Width = Unit.Percentage(60);
  18.             Controls.Add(txtUserName);

  19.             txtUserPassward = new TextBox();
  20.             txtUserPassward.ID = "txtUserPassward";
  21.             txtUserPassward.Width = Unit.Percentage(60);
  22.             Controls.Add(txtUserPassward);

  23.             submitButton = new Button();
  24.             submitButton.Text = "提交";
  25.             submitButton.CommandName = "Validate";
  26.             Controls.Add(submitButton);

  27.             ChildControlsCreated = true;
  28.         }

 
    1.首先,在之前的组合控件中,我们是把那个TextBox,Label硬编码到了生成和初始化控件的方法。CreateChildControls()中。而在模板控件中,我们没有这样做,我们只是简单的调用了模板的一个方法:InstantiateIn()。实际上,这个方法是个晚绑定。

 

    为什么是晚绑定?先来看看下面:

 

                         

 

          

    假设我们想用个下拉框来输入用户名,我们肯定要设计下拉框的属性,如 name,id,等等,当我们设置好后,就形如这样了: 

  1. <asp:DropDownList ID="mylist" runat="server" BackColor ="red" ></asp:DropDownList>

 

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

 

  1. DropDownList mylist = new DropDownList();
  2.  mylist.ID = "mylist";
  3.  mylist.Items = new ListItemCollection();
  4.  Controls.Add(mylist);

 

    其实模板控件的方法InstantiateIn()就是将之前的那个代码转换为DropDownList mylist=new DropDownList()...

 

    不知道大家清楚,说到底就是个晚绑定!!!

 

    到这里,模板控件完了,大家编译后,就后看到下面的控件:

     

               

 

   然后,我们就在html代码开发声明:如下:               

  1. <cc1:TemplateLoginControl ID="TemplateLoginControl1" runat="server">
  2.   <LoginUserNameTemplate > </LoginUserNameTemplate>
  3.              <LoginUserPasswardTemplate>
  4.                        </LoginUserPasswardTemplate>
  5.  </cc1:TemplateLoginControl>

     

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

          

 

    这样更加友好些。其实这也不难,只要加个设计器就可以了。

 

    设计器是个类。在ASP.NET有很多的设计器,如ControlDesigner,CompositeControlDesigner.等等。

 

    我们的设计器的一般都继承已有的设计器类。在这里我不多讲,大家需要的话,我专们用一章来讲。

 

  1. public class MyLoginDesigner : CompositeControlDesigner
  2. {
  3.     public override void Initialize(IComponent component)
  4.     {
  5.         base.Initialize(component);
  6.         SetViewFlags(ViewFlags.TemplateEditing, true);
  7.     }

  8.     public override string GetDesignTimeHtml()
  9.     {
  10.         TemplateLoginControl control = Component as TemplateLoginControl;
  11.         if (control != null)
  12.         {
  13.             if (control.LoginUserNameTemplate == null)
  14.             {
  15.                 return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");

  16.             }

  17.             if (control.LoginUserPasswardTemplate == null)
  18.             {
  19.                 return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
  20.             }
  21.         }
  22.         return base.GetDesignTimeHtml();
  23.     }

  24.     private TemplateGroupCollection tempgc;
  25.     public override TemplateGroupCollection TemplateGroups
  26.     {
  27.         get
  28.         {
  29.             if (tempgc == null)
  30.             {

  31.                 tempgc = base.TemplateGroups;

  32.                 TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
  33.                 loginUserNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserNameTemplate",
  34.                     Component, "UserNameTemplate", false));
  35.                 tempgc.Add(loginUserNameTemplate);

  36.                 TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
  37.                 loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
  38.                     Component, "UserPasswardTemplate", false));
  39.                 tempgc.Add(loginPasswardNameTemplate);
  40.             }
  41.             return tempgc;
  42.         }
  43.     }
  44. }

    然后在这样:

 

  1. [Designer (typeof (MyLoginDesigner ))]
  2.   public class TemplateLoginControl:Login

 

    一切就OK了,写的有些催促,大家有问题我一定回复。

 

    完整代码如下:

 

  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. using System.Web.UI.Design;
  9. using System.Web.UI.Design.WebControls ;
  10. using System.Collections ;




  11. namespace LoginControl
  12. {
  13.     [Designer (typeof (MyLoginDesigner ))]
  14.     public class TemplateLoginControl:Login
  15.     {
  16.         //声明模板#region//声明模板

  17.         private ITemplate loginUserNameTemplate;

  18.         [Browsable (false )]//我们不想在属性窗口中看见它

  19.         [TemplateContainer (typeof(TemplateLoginControl ))]//我们的模板是包含在找个控件中的,

  20.         [PersistenceMode (PersistenceMode.InnerProperty )]//模板中内容很复杂的,比如你可以拖入很多的控件

  21.         public ITemplate LoginUserNameTemplate
  22.         {
  23.             get
  24.             {
  25.                 return loginUserNameTemplate;
  26.             }
  27.             set
  28.             {
  29.                 loginUserNameTemplate = value;
  30.             }

  31.         }

  32.         private ITemplate loginUserPasswardTemplate;
  33.         [Browsable(false)]//我们不想在属性窗口中看见它

  34.         [TemplateContainer(typeof(TemplateLoginControl))]//我们的模板是包含在找个控件中的,

  35.         [PersistenceMode(PersistenceMode.InnerProperty)]//模板中内容很复杂的,比如你可以拖入很多的控件

  36.         public ITemplate LoginUserPasswardTemplate
  37.         {
  38.             get
  39.             {
  40.                 return loginUserPasswardTemplate;
  41.             }
  42.             set
  43.             {
  44.                 loginUserPasswardTemplate = value;
  45.             }
  46.         }
  47.         #endregion
  48.         重写创建控件的方法#region 重写创建控件的方法

  49.         protected override void CreateChildControls()
  50.         {
  51.             Controls.Clear();
  52.             if (loginUserNameTemplate != null)
  53.                 loginUserNameTemplate.InstantiateIn(this);
  54.             else
  55.                 base.CreateChildControls();
  56.             if(loginUserPasswardTemplate!=null )
  57.                 loginUserPasswardTemplate .InstantiateIn(this);
  58.             else
  59.                 base.CreateChildControls();

  60.             ChildControlsCreated = true;

  61.            

  62.         }

  63.         #endregion



  64.     }

  65.     public class MyLoginDesigner : CompositeControlDesigner
  66.     {
  67.         public override void Initialize(IComponent component)
  68.         {
  69.             base.Initialize(component);
  70.             SetViewFlags(ViewFlags.TemplateEditing, true);
  71.         }

  72.         public override string GetDesignTimeHtml()
  73.         {
  74.             TemplateLoginControl control = Component as TemplateLoginControl;
  75.             if (control != null)
  76.             {
  77.                 if (control.LoginUserNameTemplate == null)
  78.                 {
  79.                     return CreatePlaceHolderDesignTimeHtml("请您编辑用户名的模板");

  80.                 }

  81.                 if (control.LoginUserPasswardTemplate == null)
  82.                 {
  83.                     return CreatePlaceHolderDesignTimeHtml("请您编辑用户密码的模板");
  84.                 }
  85.             }
  86.             return base.GetDesignTimeHtml();
  87.         }

  88.         private TemplateGroupCollection tempgc;
  89.         public override TemplateGroupCollection TemplateGroups
  90.         {
  91.             get
  92.             {
  93.                 if (tempgc == null)
  94.                 {

  95.                     tempgc = base.TemplateGroups;

  96.                     TemplateGroup loginUserNameTemplate = new TemplateGroup("UserNameTemplate");
  97.                     loginUserNameTemplate.AddTemplateDefinition (new TemplateDefinition (this,"UserNameTemplate",
  98.                         Component,"UserNameTemplate",false ));
  99.                     tempgc.Add (loginUserNameTemplate );

  100.                     TemplateGroup loginPasswardNameTemplate = new TemplateGroup("UserPasswardTemplate");
  101.                     loginPasswardNameTemplate.AddTemplateDefinition(new TemplateDefinition(this, "UserPasswardTemplate",
  102.                         Component,"UserPasswardTemplate",false ));
  103.                     tempgc.Add(loginPasswardNameTemplate);
  104.                 }
  105.                 return tempgc;
  106.             }
  107.         }
  108.     }
  109.  }
阅读(769) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~