asp.net中ListView的一个Bug
2011-06-13 22:38
453 查看
作者:杨中科
今天一个学生问了一个问题,他的程序监听ListView的ItemCreated事件,然后在事件响应函数中用FindControl定位InsertTemplate中的控件,然后使用控件的ClientID进行JavaScript的注册:
if (e.Item.ItemType == ListViewItemType.InsertItem) {
TextBox TextBox1 = (TextBox)e.Item.FindControl("FirstNameTextBox");
但是运行以后发现取到的ClientID和最终渲染到浏览器的ID不一样,经过我搜索,在微软的网站上找打了官方解释,确实是ListView的一个Bug,这个Bug在ASP.Net 4.0中仍然没有修复。
文章地址:http://connect.microsoft.com/VisualStudio/feedback/details/328680/problem-accessing-controls-clientid-on-asp-net-listviews-itemcreated
On any ASP.NET ListView's ItemCreated event.
If one trying to access "ClientID" property of a certain control
inside ListView's InsertItemTemplate.
The actual client ID of that control, when it is rendered into HTML, will be corrupted
and hence the postback of that control won't fire any event
or the data cannot be bound.
微软的回复:
Thanks for reporting this issue. There is a bug in how System.Web.UI.Control caches its UniqueID if it has been accessed before its NamingContainer has been added to the control tree. This is exactly the bug you are seeing -- your custom control accesses its UniqueID property before its parent GenericWebPart (a NamingContainer) has been added to the control tree.
Unfortunately, due to performance and compatibility concerns, we are unable to fix the root cause of this issue in System.Web.UI.Control. Here are the workaround that may help your scenario:
Your current code:
protected void ListView1_ItemCreated(object sender, ListViewItemEventArgs e) {
if (e.Item.ItemType == ListViewItemType.InsertItem) {
TextBox TextBox1 = (TextBox)e.Item.FindControl("FirstNameTextBox");
if (TextBox1 != null) {
string s = TextBox1.ClientID;
<<< Error: accessing ClientID here as too early in the page lifecycle
}
}
微软给出的解决方案是使用ItemDataBound事件,但是ItemDataBound事件中不能处理InsertTemplate中的内容。我的解决方案是,虽然找到的控件的ClientID和最终生成的不一样,但是仍然能够保证唯一性,因此可以给控件设置一个额外的属性,比如myId,然后用JQuery来通过这个myId来定位控件,大体思路:
textbox1.Attributes["myId"] = textbox1.ClientID;
textbox2.Attributes["onblur"] = "$('input[myId="+textbox1.ClientID+"').text('test')";
或者完全用JQuery的next之类的方法进行定位不依赖于ID。
今天一个学生问了一个问题,他的程序监听ListView的ItemCreated事件,然后在事件响应函数中用FindControl定位InsertTemplate中的控件,然后使用控件的ClientID进行JavaScript的注册:
if (e.Item.ItemType == ListViewItemType.InsertItem) {
TextBox TextBox1 = (TextBox)e.Item.FindControl("FirstNameTextBox");
但是运行以后发现取到的ClientID和最终渲染到浏览器的ID不一样,经过我搜索,在微软的网站上找打了官方解释,确实是ListView的一个Bug,这个Bug在ASP.Net 4.0中仍然没有修复。
文章地址:http://connect.microsoft.com/VisualStudio/feedback/details/328680/problem-accessing-controls-clientid-on-asp-net-listviews-itemcreated
On any ASP.NET ListView's ItemCreated event.
If one trying to access "ClientID" property of a certain control
inside ListView's InsertItemTemplate.
The actual client ID of that control, when it is rendered into HTML, will be corrupted
and hence the postback of that control won't fire any event
or the data cannot be bound.
微软的回复:
Thanks for reporting this issue. There is a bug in how System.Web.UI.Control caches its UniqueID if it has been accessed before its NamingContainer has been added to the control tree. This is exactly the bug you are seeing -- your custom control accesses its UniqueID property before its parent GenericWebPart (a NamingContainer) has been added to the control tree.
Unfortunately, due to performance and compatibility concerns, we are unable to fix the root cause of this issue in System.Web.UI.Control. Here are the workaround that may help your scenario:
Your current code:
protected void ListView1_ItemCreated(object sender, ListViewItemEventArgs e) {
if (e.Item.ItemType == ListViewItemType.InsertItem) {
TextBox TextBox1 = (TextBox)e.Item.FindControl("FirstNameTextBox");
if (TextBox1 != null) {
string s = TextBox1.ClientID;
<<< Error: accessing ClientID here as too early in the page lifecycle
}
}
微软给出的解决方案是使用ItemDataBound事件,但是ItemDataBound事件中不能处理InsertTemplate中的内容。我的解决方案是,虽然找到的控件的ClientID和最终生成的不一样,但是仍然能够保证唯一性,因此可以给控件设置一个额外的属性,比如myId,然后用JQuery来通过这个myId来定位控件,大体思路:
textbox1.Attributes["myId"] = textbox1.ClientID;
textbox2.Attributes["onblur"] = "$('input[myId="+textbox1.ClientID+"').text('test')";
或者完全用JQuery的next之类的方法进行定位不依赖于ID。
相关文章推荐
- asp.net中ListView的一个Bug
- ASP.NET MVC SiteMap provider的一个bug
- asp.net在遨游3下的一个BUG
- asp.net 的一个新bug. 当你的程序出问题时, 不仅仅要检查自己的代码和逻辑, 还要检查微软的代码, 累吗?
- ASP.NET MVC的Ajax.ActionLink 的HttpMethod="Get" 一个重复请求的BUG
- VS 2017开发ASP.NET Core Web应用过程中发现的一个重大Bug
- 一个伴随ASP.NET从1.0到4.0的OutputCache Bug介绍
- asp.net的一个bug的发现和解决
- ASP.NET中Image控件border-width的一个诡异的BUG
- ASP.NET Community Starter Kit的一个bug
- ASP.NET Time Tracker Starter Kit的一个小bug
- 这算是ASP.NET MVC的一个大BUG吗?
- ASP.NET AJAX Futures January CTP中的一个Bug
- 似乎是发现了asp.net ajaxToolkit中TAB控件的一个BUG
- 在ASP.NET中,发现的关于string转换的一个小Bug
- 如何解决asp.net 在vs2010(.net framework 4.0)中listview控件用jquery,javascript为模版中的服务端控件注入事件的方法?因为vs2010在这个方面有存在的bug!
- ASP.NET程序运行时出现的一个小BUG
- 一个伴随ASP.NET从1.0到4.0的OutputCache Bug
- 发现 ASP.Net 的一个关于"回车提交"的 Bug ? 必须多于一个 Text 域"回车提交",Server: ButtonX_Click 才能截获!