原文:ASP.NET自定义控件组件开发 第五章 模板控件开发

第五章 模板控件开发

系列文章链接:

ASP.NET自定义控件组件开发 第一章 待续

ASP.NET自定义控件组件开发 第一章 第二篇 接着待续

ASP.NET自定义控件组件开发 第一章 第三篇

ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件

ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

ASP.NET自定义控件组件开发 第五章 模板控件开发

ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

ASP.NET2.0组件控件开发视频 初体验

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

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

开发一个模板控件一般都继承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自定义控件组件开发 第五章 模板控件开发的更多相关文章

  1. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...

  2. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl  后篇 --事件冒泡 系列文章链接: ASP.NET ...

  3. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  4. ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...

  5. 『Asp.Net 组件』第一个 Asp.Net 服务器组件:自己的文本框控件

    代码: using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace DemoWebControl ...

  6. 安全控件开发原理分析 支付宝安全控件开发 C++

    浏览器安全控件是如果支付宝一样结合web程序密码数据安全处理的程序,采用C++语言开发 通常的安全控件分为两种,一种是指支持IE内核的浏览器,一种支持所有内核的浏览器,支付宝采用的是支持所有内核的浏览 ...

  7. WP8.1学习系列(第五章)——中心控件Hub或透视控件Pivot交互UX

    具有主页菜单(中心或透视控件)的中心应用中心 你可能要设计包含许多功能的应用.当你看着这些功能时,可能会决定将它们整理到独立的区域中.这些区域最终会成为用户要访问的应用的独立部分.你需要设计一个简便的 ...

  8. 【Android】14.0 UI开发(五)——列表控件RecyclerView的瀑布布局排列实现

    1.0 列表控件RecyclerView的瀑布布局排列实现,关键词StaggeredGridLayoutManager LinearLayoutManager 实现顺序布局 GridLayoutMan ...

  9. 【WPF学习】第二十五章 日期控件

    WPF包含两个日期控件:Calender和DatePicker.这两个控件都被设计为允许用户选择日期. Calendar控件显示日期,在与Windows操作系统中看到的日历(例如,当配置系统日期时看到 ...

随机推荐

  1. 【Energy Big Data】能源互联网和电力大数据

    背景 今年的政府工作报告突出了互联网在经济结构转型中的重要地位,报告明白指出:要制定"互联网+"行动计划,推动移动互联网.云计算.大数据.物联网等与现代制造业结合,促进电子商务.工 ...

  2. 【C++】动态开辟二维数组

    二维数组在内存中的分配例如以下: C方式呈现: <span style="font-size:18px;"> #include <iostream> usi ...

  3. 关于Platinum库的MediaRender具体C++代码实现探讨

    接上篇博文 NDK下 将Platinum SDK 编译成so库 (android - upnp) 讲述了如何利用该代码库编译给android程序调用的so库,其中也提到了,在使用sample-upnp ...

  4. RequireJS学习资料

    RequireJS学习资料汇总   入门系列 [1]阮一峰 RequireJS用法 [2]RequireJS入门指南 文档系列 [1]RequireJS中文文档 [2]RequireJS英文文档 代码 ...

  5. Conversion to Dalvik format failed: Unable to execute dex

    最近莫名奇妙遇到“Conversion to Dalvik format failed: Unable to execute dex”错误,stackoverflow以后得到结果 把项目中classp ...

  6. Quartz时间配置

    格式: [秒] [分] [小时] [日] [月] [周] [年]  序号 说明  是否必填  允许填写的值 允许的通配符  1  秒  是  0-59    , - * /  2  分  是  0-5 ...

  7. Objective-C之成魔之路【9-类构造方法和成员变量作用域、以及变量】

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 构造方法 ...

  8. 高速幂 POW优化

    #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h&g ...

  9. hdu 4524 郑厂长系列故事——逃离迷宫 小水题

    郑厂长系列故事——逃离迷宫 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...

  10. 通过action 跨进程启动activity

    在一些场景中我们需要从一个进程启动另外的一个应用的activity,这有什么好办法? 这里介绍一种方法,通过自定义 action 通过filter来启动. 如果你需要启动一个你自己写的另一个app的a ...