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

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:-)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值