浅析Page.LoadTemplate("模板")方法动态获取绑定模板后,通过FindControl获取服务端控件的方法。
2007-04-28 10:22
756 查看
平常使用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直接找到模板里面的控件的原因了。
<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直接找到模板里面的控件的原因了。
相关文章推荐
- DataForm中包含TabControl控件,FindNameInContent方法无法获取未选中TabItem里的控件问题
- DataForm中包含TabControl控件,FindNameInContent方法无法获取未选中TabItem里的控件问题
- 模板里的控件要用FindControl(id)方法读取
- 关于DataGrid Web Control 动态绑定2--子控件的获取
- Vue input控件通过value绑定动态属性及修饰符的方法
- GridView 动态添加模板列并绑定数据 实现从外部直接传入控件 和 绑定字段参数
- DevExpress 图表控件:ChartControl 动态绑定数据
- 黑马程序员——通过反射Proxy类的静态函数getProxyClass()来获取动态生成类的构造函数和方法
- Android在onCreate()方法中动态获取TextView控件的高度
- bootstrap table之通用方法( 时间控件,导出,动态下拉框, 表单验证 ,选中与获取信息)代码分享
- 动态获取一个服务端控件的客户端ID
- FormView里用FindControl找不到控件的解决方法
- PreviousPage.FindControl遇到MasterPage查找控件的方法
- 通过数据绑定模板得到对应的Item控件
- WPF 获取ControlTemplate 中的控件方法
- 安卓中通过循环动态添加了一堆自定义的控件,怎么给这些控件绑定事件?
- vc 多个菜单 绑定一个 方法 获取对应控件id
- 将一个枚举类型动态绑定到一个列表控件的方法
- 解决使用MasterPage后,Page.FindControl方法找不到指定控件的问题
- dwz 通过js 动态生成的查找找回按钮需要手动绑定lookup() 方法