C# 回发后,Listview 未在 databind() 上完全更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/821053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Listview not fully updating on databind() after postback
提问by patjbs
I have a ListView control which is exhibiting an odd behaviour - rows are only partially updating after a postback. I'm hoping someone here can shed some light on why this might be occuring.
我有一个 ListView 控件,它表现出一种奇怪的行为 - 行在回发后仅部分更新。我希望这里有人可以解释为什么会发生这种情况。
My listview DataSource is bound to a List of items which is stored in the page session state. This is intentional, partially to timeout out-of-date views since multiple users view the data. On a plain resort operation, the sorting is handled on page via javascript, and the list/session data order is kept in sync via callbacks. Callback also checks for permissions levels. On a particular resort operation that is more complicated, the javascript on the page makes a postback to the page to handle the sorting logic. The List/Session is updated as in the callback, then the listview control is rebound to the data. The page loads again, and the rows show the new order. No problem, right?
我的列表视图数据源绑定到存储在页面会话状态中的项目列表。这是有意的,部分是为了使过期视图超时,因为多个用户查看数据。在普通的度假村操作中,排序是通过 javascript 在页面上处理的,并且列表/会话数据顺序通过回调保持同步。回调还会检查权限级别。在更复杂的特定度假村操作中,页面上的 javascript 会回发到页面以处理排序逻辑。在回调中更新列表/会话,然后将列表视图控件重新绑定到数据。页面再次加载,行显示新订单。没问题吧?
The problem is that someof the elements in the listview do not change value in accordance with the new order. While the hyperlinks and text that is processed on page (ie like <%# Eval("ProjectAbbrev") %>) are updated appropriately, checkboxes, literals, and dropdowns that have their values set via the OnItemDataBound event method are not - they stay "frozen" in place, even though stepping through the code reveals that the method is run during the postback, and that the controls SHOULD be set to their new values. If I go and manually truncate the list to say, half the original size, sure enough only those items are repopulated, but the checkboxes and such still retain their original values.
问题是listview中的一些元素没有按照新的顺序改变值。虽然在页面上处理的超链接和文本(例如 <%# Eval("ProjectAbbrev") %>)被适当更新,但通过 OnItemDataBound 事件方法设置其值的复选框、文字和下拉列表不是 - 它们保留“冻结”到位,即使单步执行代码显示该方法在回发期间运行,并且控件应该设置为它们的新值。如果我手动截断列表以说原始大小的一半,当然只有那些项目被重新填充,但复选框等仍然保留其原始值。
So my question is: Why aren't these elements updating along with the rest of the listview control elements on the postback? I have the feeling that I'm either misunderstanding the page lifecycle in ASP.NET or that I've encountered a bug of some kind.
所以我的问题是:为什么这些元素不随回发中的其余列表视图控件元素一起更新?我感觉我要么误解了 ASP.NET 中的页面生命周期,要么遇到了某种错误。
At this point I'm thinking I will have to move the more complicated sorting operation to the page in javascript, but that will be rather tricky and I'd like to avoid doing so if possible.
在这一点上,我想我必须将更复杂的排序操作移动到 javascript 中的页面,但这会相当棘手,如果可能的话,我想避免这样做。
更新:我已经尝试将 EnableViewState 设置为 false 并且它没有解决这个问题。在任何情况下我都不能使用这种策略,因为页面的其他部分(保存)最终依赖于读取视图状态。
更新:我提供了一些代码片段,希望它们可以对这个问题有所了解:
Page: The HyperLink element will update properly after postback, but the CheckBox which has its value assigned in the OnQueueRepeater_ItemDataBound method, will stay the same.
页面:HyperLink 元素将在回发后正确更新,但在 OnQueueRepeater_ItemDataBound 方法中赋值的 CheckBox 将保持不变。
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TextProcessorProjects.ascx.cs" Inherits="ETD.UI.Controls.TextProcessorProjects" %>
<asp:ListView ID="QueueListView" runat="server" OnItemDataBound="OnQueueRepeater_ItemDataBound">
<ItemTemplate>
<tr>
<td><asp:HyperLink runat="server" ID="ProjectIDLink"><%# Eval("ProjectAbbrev") %></asp:HyperLink></td>
<td><asp:CheckBox runat="server" ID="ScannedCheckBox" BorderStyle="None" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
Code behind: On postback, the following code executes:
代码隐藏:在回发时,执行以下代码:
protected List<Book> QueueDataItems
{
get { return (List<Book>)Session["Queue"]; }
set { Session["Queue"] = value; }
}
else if (IsPostBack && !Page.IsCallback)
{
// resort QueueDataItems List appropriately
ResortQueue(Request.Params)
// rebind
QueueListView.DataSource = QueueDataItems;
QueueListView.DataBind();
}
protected void OnQueueRepeater_ItemDataBound(object sender, ListViewItemEventArgs e)
{
// ...
// ... other controls set
CheckBox scannedCheckBox = e.Item.FindControl("ScannedCheckBox") as CheckBox;
scannedCheckBox.Checked = book.Scanned;
}
UPDATE: I've given up on getting this to work and moved my sorting logic to the client side with javascript. If anyone has any ideas as to why this odd behaviour was happening though, I'd still be very interested in hearing them!
更新:我已经放弃了让它工作并使用javascript将我的排序逻辑移到客户端。如果有人对为什么会发生这种奇怪的行为有任何想法,我仍然很想听听他们的意见!
采纳答案by tim
out of interest, what point on the page are you databinding on? Page_Load?
出于兴趣,您在页面上的哪个点进行数据绑定?页面_加载?
Try it on OnPreRender - might help out.
在 OnPreRender 上试试 - 可能会有所帮助。
回答by CB01
Sounds like the ViewState is kicking in and repopulating the data. In any case, if you are Databinding in every postback anyways, you should probably set the EnableViewState of your ListView to false to reduce page size.
听起来 ViewState 正在启动并重新填充数据。在任何情况下,如果您在每次回发中都进行数据绑定,您可能应该将 ListView 的 EnableViewState 设置为 false 以减小页面大小。
回答by Christian Hagelid
Maybe your QueueListView is getting re-bound for some reason.
也许您的 QueueListView 由于某种原因被重新绑定。
Try resetting the DataSource value after the DataBind() to see what happens
尝试在 DataBind() 之后重置 DataSource 值以查看会发生什么
QueueListView.DataBind();
QueueListView.DataSource = null;
回答by Christian Hagelid
Any chance this could be a caching issue? I ran into a similar issue using a listview with an XMLDatasource. I tried turning off all the viewstate. I would bind the listview in the code behind and use XPath to write it all out to the screen on my aspx page. This was used in a search....the next time I did a search, none of the new information showed up. The reason is because an XMLDatasource has caching enabled by default. In my case I was hitting the DB every time and had no need to cache it. I turned off the caching on the datasource and all my problems were fixed.
这可能是缓存问题吗?我在使用带有 XMLDatasource 的列表视图时遇到了类似的问题。我尝试关闭所有视图状态。我会在后面的代码中绑定列表视图,并使用 XPath 将它全部写到我的 aspx 页面上的屏幕上。这是在搜索中使用的......下次我进行搜索时,没有任何新信息出现。原因是因为 XMLDatasource 默认启用了缓存。在我的情况下,我每次都在访问数据库并且不需要缓存它。我关闭了数据源上的缓存,我的所有问题都得到了解决。
I only mention this because the error I was having sounds identical to yours. I can't see how you're retrieving book in the itemdatabound - and you're not using an XML Datasource by the looks of things.....but I thought the comment might trigger something for you. Good luck....though it sounds like you've already moved on :-).
我之所以提到这一点,是因为我遇到的错误听起来与您的相同。我看不出你是如何在 itemdatabound 中检索书籍的——而且从外观上看,你没有使用 XML 数据源......但我认为评论可能会为你触发一些事情。祝你好运......虽然听起来你已经继续前进了:-)。
回答by Drithyin
Is the checkbox control ReadOnly=true or Enabled=false?
复选框控件是 ReadOnly=true 还是 Enabled=false?
I have had trouble with controls with one of these properties set as above not updating no matter how I try to manhandle the control in the code behind. I would think disabling the viewstate would also bypass that little "feature" of ASP.NET, but it's worth a shot.
无论我如何尝试在后面的代码中手动处理控件,我都遇到了具有上述设置的这些属性之一的控件不更新的问题。我认为禁用视图状态也会绕过 ASP.NET 的那个小“功能”,但值得一试。
Also, if the items are sorted via clientside code, is that ordering preserved on the postback? I don't think that you can alter the CLR object you have in session via javascript.
此外,如果项目是通过客户端代码排序的,那么回发中是否保留了该排序?我不认为您可以通过 javascript 更改会话中的 CLR 对象。
回答by o.k.w
Not sure if this helps, replace <%# Eval("ProjectAbbrev") %> with the Hyperlink.Text assigned in the OnQueueRepeater_ItemDataBound method and see if all rows get populated correctly.
不确定这是否有帮助,将 <%# Eval("ProjectAbbrev") %> 替换为在 OnQueueRepeater_ItemDataBound 方法中分配的 Hyperlink.Text 并查看是否所有行都被正确填充。
This probably won't solve your problem, but will be interesting to know the result.
这可能不会解决您的问题,但知道结果会很有趣。
回答by awe
I think this is related to the order of when the different events are triggered during the page lifecycle. See ASP.NET Page Life Cycle Overview. You should do databinding in Page_OnPreRender to make sure the replopulating is done after control events (that will cause data updating) on the page.
我认为这与页面生命周期中触发不同事件的顺序有关。请参阅ASP.NET 页面生命周期概述。您应该在 Page_OnPreRender 中进行数据绑定,以确保在页面上的控制事件(这将导致数据更新)之后进行重新填充。