Asp.net控件开发学习笔记(十一)----服务器控件模板

转载 2013年12月03日 11:26:22

Asp.net控件开发学习笔记(十一)----服务器控件模板

   Asp.net 2.0以后的版本,Asp.net提供了服务器控件模板(Template)和数据绑定(Data Bind)来简化开发工作,模板是是用于定制化服务器控件或者HTML如何在页面呈现,而模板和数据绑定往往结合起来在一起实现更高级的功能,比如最经典的GridView.例如,在 GridView服务器控件中可以使用 HTML 元素和控件的组合来创建列表中每行的布局。同样,GridView服务器控件对网格中的每行都具有一个默认的外观。但是,您可以通过为单个行、间隔行、所选行等行定义不同的模板来自定义网格的外观。

 

定制控件内容

   模板用于让开发人员自定义HTML或者服务器控件作为主要控件输出流的一部分。提供了模板的服务器控件其实是给予插入自定义内容提供了容器。

   服务器控件模板的强大之处在于它通过让开发人员可以定制输出特定的html来给予了开发人员极高的灵活性.如下图:

   

 

使用服务器控件模板

使用服务器控件模板的一大好处是我们可以专注开发空间,而把外观等htmlcss设置内容让其他人来完成。

   GridView控件里,我们可以通过在ItemTemplate里设置任何我们想设置的内容,在DropDownList控件中我们可以插入ListItem子控件,但在里面插入比如TextBox控件则不行。这个原因就要说到下面一个标签(Attribute)

 

ParseChildren Attribute

   服务器控件必须通过在类声明时添加ParseChildren标签来告诉asp.net页面分析器这个控件需要支持模板。ParseChildren的功能是让服务器控件所含有的子控件作为它的一个属性存在。

 对于继承System.Web.UI.WebControls.WebControl基类的控件,这个标签已经通过继承而存在不需要再声明

 ParseChildren标签还暴露了ChildrenAsProperties属性,在使用

可以:ParseChildrenAttribute(ChildrenAsProperties = true)

也可以用简便写法:ParseChildren(true)

   ChildrenAsProperty属性的作用是让控件的属性和直接在控件内部的html代码,或者说是XML代码(“<”和”>”)进行匹配.如下图:

  

而不使用ChildrenAsProperties属性的则会是如下图:

 

下面通过一个Demo来看

Demo 服务器导航菜单

   先看Demo的效果

  

  

先声明两个用于存放子控件的容器,代码如下:

    public class BasicTemplateContainer : WebControlINamingContainer

    {

        public BasicTemplateContainer(): base(HtmlTextWriterTag.Div)

        {

            this.BorderWidth = 1;

            this.BorderStyle = BorderStyle.Solid;

        }

    }

    public class SeperatorTemplateContainer : WebControlINamingContainer

    {

        public SeperatorTemplateContainer(): base(HtmlTextWriterTag.Span)

        {

        }

 }

第一个用于存放HeaderTemplate和footerTemplate,而第二个用于存放分隔符

再声明一个存放菜单超链接的容器,代码如下:

    [TypeConverter(typeof(ExpandableObjectConverter))]

    public class MenuItemData

    {

        public MenuItemData()

        {

        }

        [NotifyParentProperty(true)]

        public string Title { getset; }

        [NotifyParentProperty(true)]

        public string Url { getset; }

        [NotifyParentProperty(true)]

        public string ImageUrl { getset; }

        [NotifyParentProperty(true)]

        public string Target { getset; }

    }

最后声明一个继承于CompositeControl基类的控件,声明代码如下:

public class TemplateMenu : CompositeControl

最终完全代码如下:

 


  1 using System;
  2 using System.Web;
  3 using System.Web.UI;
  4 using System.Web.UI.WebControls;
  5 using System.Collections;
  6 using System.ComponentModel;
  7 using System.Web.UI.WebControls;
  8 namespace bindcontrol
  9 {
 10     [ToolboxData("<{0}:templatemenu runat=server></{0}:templatemenu>")]
 11     public class TemplateMenu : CompositeControl
 12     {
 13         private ArrayList menuData;
 14         public TemplateMenu(): base()
 15         {
 16         menuData = new ArrayList(){
 17 
 18             new MenuItemData{Title="博客园", Url="http://www.cnblogs.com"},
 19             new MenuItemData{Title="Microsoft", Url="http://www.microsoft.com"},
 20             new MenuItemData{Title="ASP.Net", Url="http://asp.net"}};
 21         }
 22         private ITemplate headerTemplate;
 23         [Browsable(false), Description("The header template"),
 24         PersistenceMode(PersistenceMode.InnerProperty),
 25         TemplateContainer(typeof(BasicTemplateContainer))]
 26         public ITemplate HeaderTemplate
 27         {
 28             get
 29             {
 30                 return headerTemplate;
 31             }
 32             set
 33             {
 34                 headerTemplate = value;
 35             }
 36         }
 37         private ITemplate footerTemplate;
 38         [Browsable(false), Description("The footer template"),
 39         PersistenceMode(PersistenceMode.InnerProperty),
 40         TemplateContainer(typeof(BasicTemplateContainer))]
 41         public ITemplate FooterTemplate
 42         {
 43             get
 44             {
 45                 return footerTemplate;
 46             }
 47             set
 48             {
 49                 footerTemplate = value;
 50             }
 51         }
 52         private ITemplate separatorTemplate;
 53         [Browsable(false), Description("The separator template"),
 54         PersistenceMode(PersistenceMode.InnerProperty),
 55         TemplateContainer(typeof(SeperatorTemplateContainer))]
 56         public ITemplate SeparatorTemplate
 57         {
 58             get
 59             {
 60                 return separatorTemplate;
 61             }
 62             set
 63             {
 64                 separatorTemplate = value;
 65             }
 66         }
 67         private void CreateControlHierarchy()
 68         {
 69             if (HeaderTemplate != null)
 70             {
 71                 BasicTemplateContainer header = new BasicTemplateContainer();
 72                 HeaderTemplate.InstantiateIn(header);
 73                 Controls.Add(header);
 74             }
 75             int count = menuData.Count;
 76             for (int index = 0; index < count; index++)
 77             {
 78                 MenuItemData itemdata = (MenuItemData)menuData[index];
 79                 HyperLink link = new HyperLink()
 80                 {
 81                     Text = itemdata.Title,
 82                     NavigateUrl = itemdata.Url,
 83                     ImageUrl = itemdata.ImageUrl,
 84                     Target = itemdata.Target
 85                 };
 86                 Controls.Add(link);
 87                 if (index != count - 1)
 88                 {
 89                     if (SeparatorTemplate != null)
 90                     {
 91                         SeperatorTemplateContainer separator = new SeperatorTemplateContainer();
 92                         SeparatorTemplate.InstantiateIn(separator);
 93                         Controls.Add(separator);
 94                     }
 95                     else
 96                     {
 97                         Controls.Add(new LiteralControl(" | "));
 98                     }
 99                 }
100             }
101             if (FooterTemplate != null)
102             {
103                 BasicTemplateContainer footer = new BasicTemplateContainer();
104                 FooterTemplate.InstantiateIn(footer);
105                 Controls.Add(footer);
106             }
107         }
108         override protected void CreateChildControls()
109         {
110             Controls.Clear();
111             CreateControlHierarchy();
112         }
113         public override ControlCollection Controls
114         {
115             get
116             {
117                 EnsureChildControls();
118                 return base.Controls;
119             }
120         }
121     }
122 
123     public class BasicTemplateContainer : WebControl, INamingContainer
124     {
125         public BasicTemplateContainer(): base(HtmlTextWriterTag.Div)
126         {
127             this.BorderWidth = 1;
128             this.BorderStyle = BorderStyle.Solid;
129         }
130     }
131     public class SeperatorTemplateContainer : WebControl, INamingContainer
132     {
133         public SeperatorTemplateContainer(): base(HtmlTextWriterTag.Span)
134         {
135         }
136     }
137     [TypeConverter(typeof(ExpandableObjectConverter))]
138     public class MenuItemData
139     {
140         public MenuItemData()
141         {
142         }
143         [NotifyParentProperty(true)]
144         public string Title { getset; }
145         [NotifyParentProperty(true)]
146         public string Url { getset; }
147         [NotifyParentProperty(true)]
148         public string ImageUrl { getset; }
149         [NotifyParentProperty(true)]
150         public string Target { getset; }
151     }
152 }

前台调用代码如下:

首先注册控件:<%@ Register Namespace="bindcontrol" TagPrefix="dd" %>

然后是前台代码:

<dd:TemplateMenu runat="server" >

       <HeaderTemplate>template header</HeaderTemplate>

       <SeparatorTemplate>%</SeparatorTemplate>

       <FooterTemplate>template footer</FooterTemplate>

    </dd:TemplateMenu>

注意,作为模板的类型必须声明成ITemplate类型,而这个ITemplate的具体类型则通过TemplateContainer标签进行注入.我们通过声明CreateControlHierarchy()函数来进行控制控件的具体输出,最后通过覆盖父类的CreateChildControls()方法来调用我们写好的CreateControlHierarchy方法达到控制输出的目的。

 

   最后,你可能有疑问,那个神奇的ChildrenAsProperties属性跑哪去了?如果没有这个属性,那上面<headerTemplate>之类的标签又是如何匹配的呢?还记得吗,继承与WebControl基类的控件继承了这个标签,所以不用显示声明,所以ChildrenAsProperties属性come for free:-)

ESP8266学习笔记2:实现ESP8266的局域网内通信

上一篇熟悉了编译下载操作,现在就以实例入手。工程使用的是IOT_DEMO,据DEMO文档可以知道ESP8266初始工作模式为softAP+station共存的模式。于是这边我们就先以softAP入手,...
  • zddxmu
  • zddxmu
  • 2015年07月09日 00:05
  • 12137

ASP.NET基础与入门:WebForm,事件驱动编程,Page类

注:因为这个暑假做了一个ASP.NET的项目(WebForms模式),暑假期间太忙没有来得及整理,现在统一梳理下知识(有些我认为可以跟HTML共通的就没记)推荐几个学习ASP.NET的网站:W3Sch...
  • Jurbo
  • Jurbo
  • 2016年08月29日 15:10
  • 4473

ASP.NET自定义服务器控件

最简单的服务器端控件开发流程简介。
  • yanwushu
  • yanwushu
  • 2014年04月08日 21:34
  • 4309

ASP.Net WebForm学习笔记:一、aspx与服务器控件探秘

作者:周旭龙 出处:http://edisonchou.cnblogs.com 开篇:毫无疑问,ASP.Net WebForm是微软推出的一个跨时代的Web开发模式,它...
  • u011069590
  • u011069590
  • 2015年09月23日 14:03
  • 783

Asp.net控件开发学习笔记(九)----服务器控件事件

EventCollection 如果在单个控件中有多个事件,那么使用System.ComponentModel.EventHandlerList对事件进行保存将会在内存占用上有不错的提高。Event...
  • ytbhhws
  • ytbhhws
  • 2013年11月05日 14:28
  • 597

ASP.NET(三) Web开发——常用服务器控件

Asp.net在客户端开发和web开发所用到的控件还是有很大的差别的,而且Web开发的界面是在浏览器中显示的,所以控件的设计都和前边学习HTML设计有联系,没有客户端开发那么简单,不过我们可以通过专门...
  • liujiahan629629
  • liujiahan629629
  • 2013年05月19日 16:45
  • 5031

Asp.Net学习之基于web服务器控件(一)

ASP是一种使嵌入网页中的脚本可由因特网服务器执行的服务器端脚本技术。 指 Active Server Pages(动态服务器页面) ,运行于 IIS 之中的程序....
  • wn795
  • wn795
  • 2014年11月04日 17:39
  • 395

ASP.NET 服务器控件开发技术与实例 光盘源码

  • 2007年09月14日 17:37
  • 2.18MB
  • 下载

asp.net 自定义服务器控件属性 [Bindable(true)]...

asp.net 自定义服务器控 [Bindable(true)]... 自定义服务器控件属性的特性: Bindable 这个特性表示属性是否可以绑定一个有效数据源。通常使用布尔值进行设置。例...
  • lllljz
  • lllljz
  • 2013年01月24日 18:37
  • 895

ASP.NET 部署和使用自定义 Web 服务器控件

本演练演示如何创建和测试自定义 ASP.NET Web 服务器控件。 在本演练中,您将学会如何执行以下任务: 创建一个 ASP.NET Web 服务器控件。 通过向该控件添加元数据来...
  • qq285679784
  • qq285679784
  • 2017年06月16日 09:39
  • 930
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Asp.net控件开发学习笔记(十一)----服务器控件模板
举报原因:
原因补充:

(最多只允许输入30个字)