自定义控件的构建(11)

  这一节主要涉及到数据绑定控件,如GridView一类,对于ASP.NET Framework中的任何内容,都可以进行扩展,那么数据绑定控件也不例外

  对于ListView之类,其都是用ItemTemplate格式化数据的,所以首先介绍一下 ItemTemplate的实现

  ITemplate接口

  其包含了一个InstantiateIn(),这个方法用于实例化控件中模板的内容,但不是必须实现它,ASP.NET Framework会自动的创建并调用它。

    /// <summary>
    /// 使用模板显示
    /// </summary>
    public class ItemTempletControl:CompositeControl
    {
        private ITemplate _itemTemplete;
        [TemplateContainer(typeof(ItemTempletControl))]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ItemTemplete
        {
          get { return _itemTemplete; }
          set { _itemTemplete = value; }
        }
        public string Title { get;set; }
        public string Author{ get;set; }
        protected override void CreateChildControls()
        {
            _itemTemplete.InstantiateIn(this);
        }

这个ItemTempletControl包含了一个返回ITemplete的ItemTemplete属性,可以看到,其被TemplateContainer,PersistenceMode两个特性修饰了

其中TemplateContainer表示包含这个模板的控件类型,PersistenceMode表示在页面中的保存方式,其值是个枚举值。

可以看一看,这个控件的声明方式

    <custom:ItemTempletControl ID="ItemTemplet1"  runat="server" >
    <ItemTemplete></ItemTemplete>
    </custom:ItemTempletControl>

这个是我们很熟悉的模板,因为我们代码中将PersistenceMode设置为InnerProperty了。所有ItemTemplete作为一个子控件添加到了ItemTempletControl中

我们看一看这个控件是如何使用的,这里并不是我们的重点,因为后面还会讲到,所以也算做个伏笔。

页面定义:

    <custom:ItemTempletControl ID="ItemTemplet1"  runat="server" >
    <ItemTemplete>
     <%#Container.Author %>
     <%#Container.Title %>
    </ItemTemplete>
    </custom:ItemTempletControl>
后台编码
         this.ItemTemplet1.Title  = "123";
         this.ItemTemplet1.Author = "123";
         this.ItemTemplet1.DataBind();

这样,我们就会收到我们期望的结果了。这里用了<%#Container.Author %> 这种形式,Container引用了当前绑定容器,

这个例子中绑定容器就是ItemTempletControl。最后提醒的是不要忘了DataBind(),否则是看不出效果的。

默认模板

  上面提到InstantiateIn()也可以不用实现,但那只是在不需要默认模板的情况下。

  对上面的例子进行一些修改,使用默认模板

控件本身没有太大变化

 public class ItemTempletWithDefalutControl : CompositeControl
    {
        private ITemplate _itemTemplete;
        [TemplateContainer(typeof(ItemTempletWithDefalutControl))]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ItemTemplete
        {
            get { return _itemTemplete; }
            set { _itemTemplete = value; }
        }
        public string Title { get; set; }
        public string Author { get; set; }
        protected override void CreateChildControls()
        {
            if (_itemTemplete == null)
                _itemTemplete = new WithDefaultTemplet();
             _itemTemplete.InstantiateIn(this);
        }
    }

可以看到CreateChildControls()已经做了修改,它用于检测是否有ItemTemplet,没有的话则创建WithDefaultTemplet实例,这里的WithDefaultTemplet

就是我们自己定制的模板

 public class WithDefaultTemplet : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            Label labtitle = new Label();
            labtitle.DataBinding += new EventHandler(labtitle_DataBinding);
            Label labAuthor = new Label();
            labAuthor.DataBinding += new EventHandler(labAuthor_DataBinding);
            container.Controls.Add(labtitle);
            container.Controls.Add(new LiteralControl("<br/>"));
            container.Controls.Add(labAuthor);
            container.Controls.Add(new LiteralControl("<br/>"));
        }
        void labAuthor_DataBinding(object sender, EventArgs e)
        {
            Label lbl=(Label)sender;
            ItemTempletWithDefalutControl item = (ItemTempletWithDefalutControl)lbl.NamingContainer;
            lbl.Text = item.Author;
        }
        void labtitle_DataBinding(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            ItemTempletWithDefalutControl item = (ItemTempletWithDefalutControl)lbl.NamingContainer;
            lbl.Text = item.Title;
        }
    }

这个类就具体实现了InstantiateIn(),注意代码中创建的3个Label,当调用DataBind()时,会引发DataBinding()。

    <custom:ItemTempletWithDefalutControl ID="WithDefalutControl1" runat="server">
    </custom:ItemTempletWithDefalutControl>
后台实例化:
       this.WithDefalutControl1.Title = "123";
       this.WithDefalutControl1.Author= "234";
       this.WithDefalutControl1.DataBind();
很明显,ItemTempletWithDefalutControl()并未包含ItemTemplate,当浏览器显示页面时,ItemTemplet的内容由WithDefaultTemplet负责呈现
 
 
本文参考了《ASP.NET 3.5 揭秘》
posted @ 2010-08-09 13:01  ringgo  阅读(687)  评论(0编辑  收藏  举报