浅析Page.LoadTemplate("模板")方法动态获取绑定模板后,通过FindControl获取服务端控件的方法。...

平常使用DataList数据控件绑定数据时,都是在ItemTemplate项里面放入
< asp:DataList  ID ="list2"  runat ="server" >
            
< ItemTemplate >
                
< asp:HyperLink   ID ="hl"  runat ="server" >
                
</ asp:HyperLink >
            
</ ItemTemplate >
        
</ asp:DataList >
之类的服务器控件,然后再通过list_ItemDataBound事件获取相应的值
void  list2_ItemDataBound( object  sender, DataListItemEventArgs e)
        {
            HyperLink hl 
=  (HyperLink)e.Item.FindControl( " hl " );

            hl.Text 
=  DataBinder.Eval(e.Item.DataItem,  " name " ).ToString();

            hl.NavigateUrl 
=   " ./default.aspx " ;
        }


但是DataList的ItemTemplate有些时候是不固定的,需要从Page.LoadTemplate("模板的路径")方法里面加载。这样的话通过e.Item.FindControl("服务器控件ID")就无法找到相应的服务器控件。为什么呢?

        通过分析e.Item入手,可以做两个不同的绑定然后进行跟踪对比,首先按照常规的绑定办法在跟踪list2_ItemDataBound事件中的e.Item 。在list2_ItemDataBound方法中通过以下的方法

ControlCollection ctrl  =  e.Item.Controls;

 

找出e.Item中所有的服务器控件,调试ctrl变量

 

 就可以发现controls[1]事实上就是通过e.Item.FindControl能查找到的ID为"hl"的HyperLink控件了。

第2个例子通过Page.LoadTemplate("模板ID")方法来加载临时的模板,首先建立一个文本文件命名为temp.ascx(改掉文本文件的后缀名)。内容如下

< asp:Label  ID ="lbl"  runat ="server" >
</ asp:Label >

 然后在后台定义一个DataList并指明触发绑定的相关事件

      
                DataList list 
=   new  DataList();
                list.ItemTemplate 
=  Page.LoadTemplate( " temp.ascx " );
                list.ItemDataBound 
+=   new  DataListItemEventHandler(list_ItemDataBound);
                list.DataSource 
=  dt;
                list.DataBind();

 在list_ItemDataBound事件中定义一个和刚才一样的控件集合用于跟踪

ControlCollection ctrlcollection   =  e.Item.Controls;

 

 调试 ctrlcollection

很显然通过e.Item.FindControl显然找不到想要之前在模板定义ID为"lbl"的Label控件。而是找到他的父级的容器即之前定义的模板temp.ascx。而且ctrlcollection.Count=1.也就说明了e.Item下面包含的子容器也就只有temp.ascx。
也就是说可以通过查找e.Item.Controls[0]找到lbl了。尝试跟踪一下e.Item.Controls[0]

Control ctrl  =  e.Item.Controls[ 0 ];

 

 

 

在上面的跟踪通过ctrl找到ID为lbl的控件也就是说e.item是包含了lbl的父级容器而不是直接包含了lbl本身。问题找到了就好解决。把原来list_ItemDataBound的方法修改为如下:

   void  list_ItemDataBound( object  sender, DataListItemEventArgs e)
        {
            Control ctrl 
=  e.Item.Controls[ 0 ];
            Label lbl 
=  (Label)ctrl.FindControl( " lbl " );
            lbl.Text 
=  DataBinder.Eval(e.Item.DataItem,  " name " ).ToString();
        }

 


总结:通过Page.LoadTemplate("...")方法加载临时的模板和在页面中直接使用还是有所不同的,直接使用的模板e.Item就是控件的父级容器,而加载模板的方式e.Item只是模板的父级容器,也就是说e.Item应该属于模板里面控件的父级的容器,这也就是为什么在加载模板的情况下不能通过e.Item.FindControl直接找到模板里面的控件的原因了。

 

自己试了下,代码如下:

 

ExpandedBlockStart.gif 代码
public   partial   class  WebForm1 : System.Web.UI.Page
    {
        
protected   void  Page_Load( object  sender, EventArgs e)
        {
            DlBinds();
        }

        
private   void  DlBinds()
        {
            DataList list 
=   new  DataList();

            DataTable dt 
=   new  DataTable();

            list.HeaderTemplate 
=  Page.LoadTemplate( " HeadTemp.ascx " );

            list.ItemTemplate 
=  Page.LoadTemplate( " Temp.ascx " );

            dt.Columns.Add(
" name " typeof (String));

            dt.Rows.Add(
new  Object[] {  " 张三 "  });
            dt.Rows.Add(
new  Object[] {  " 李四 "  });

            list.ItemDataBound 
+=   new  DataListItemEventHandler(DataList1_ItemDataBound);

            list.DataSource 
=  dt;
            list.DataBind();

            Page.Controls.Add(list);

        }


        
protected   void  DataList1_ItemDataBound( object  sender, DataListItemEventArgs e)
        {
            
if  (e.Item.ItemType  ==  ListItemType.Item  ||  e.Item.ItemType  ==  ListItemType.AlternatingItem)
            {
                Control ctrl
= e.Item.Controls[ 0 ];

                Label lbl
=  ctrl.FindControl( " lbl " as  Label;

                lbl.Text 
=  DataBinder.Eval(e.Item.DataItem, " name " ).ToString();
            }
        }
    }

 

转载于:https://www.cnblogs.com/jhxk/articles/1801050.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值