Listview在回发后没有完全更新databind()

时间:2009-05-04 17:28:37

标签: c# asp.net data-binding listview postback

我有一个表现出奇怪行为的ListView控件 - 回发后行只是部分更新。我希望这里有人可以解释为什么会出现这种情况。

我的listview DataSource绑定到存储在页面会话状态中的项目列表。这是故意的,部分是为了超时过期的视图,因为多个用户查看数据。在普通的度假村操作中,通过javascript在页面上处理排序,并且通过回调使列表/会话数据顺序保持同步。回调还会检查权限级别。在更复杂的特定度假操作上,页面上的javascript对页面进行回发以处理排序逻辑。列表/会话在回调中更新,然后列表视图控件将反弹到数据。页面再次加载,行显示新订单。没问题,对吧?

问题是列表视图中 某些 元素不会根据新订单更改值。虽然在页面上处理的超链接和文本(例如<%#Eval(“ProjectAbbrev”)%>)会得到适当更新,但是通过OnItemDataBound事件方法设置其值的复选框,文字和下拉列表不是 - 它们保持“冻结”到位,即使单步执行代码显示该方法在回发期间运行,并且控件应该设置为它们的新值。如果我去手动截断列表,说原始大小的一半,确定只重新填充那些项目,但复选框等仍然保留其原始值。

所以我的问题是:为什么这些元素不会与回发中的其余listview控件元素一起更新?我觉得我要么误解了ASP.NET中的页面生命周期,要么我遇到了某种错误。

此时我想我将不得不在javascript中将更复杂的排序操作移动到页面,但这将是相当棘手的,我希望尽可能避免这样做。

<小时/> 更新:我已经尝试将EnableViewState设置为false,但它不能解决这个问题。在任何情况下我都无法使用该策略,因为页面的其他部分(保存)最终依赖于读取视图状态。
更新:我提供了一些代码片段,希望他们可以对这个问题有所了解:

页面: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>

代码隐藏:在回发时,执行以下代码:

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;
}

更新:我已经放弃了让它工作并使用javascript将我的排序逻辑移动到客户端。如果有人对为什么会发生这种奇怪的行为有任何想法,我仍然对听到它们非常感兴趣!

7 个答案:

答案 0 :(得分:6)

出于兴趣,页面上的哪一点是你数据绑定? Page_Load中?

在OnPreRender上尝试 - 可能会有所帮助。

答案 1 :(得分:2)

听起来像ViewState正在开始并重新填充数据。 无论如何,如果你在每个回发中都是数据绑定,你应该将ListView的EnableViewState设置为false以减小页面大小。

答案 2 :(得分:2)

我认为这与在页面生命周期中触发不同事件的顺序有关。见ASP.NET Page Life Cycle Overview。您应该在Page_OnPreRender中进行数据绑定,以确保在页面上的控制事件(将导致数据更新)之后完成重新填充。

答案 3 :(得分:0)

也许你的QueueListView因某种原因而被重新绑定。

尝试在DataBind()之后重置DataSource值以查看发生的情况

QueueListView.DataBind();
QueueListView.DataSource = null;

答案 4 :(得分:0)

这可能是一个缓存问题吗?我使用带有XMLDatasource的listview遇到了类似的问题。我试图关闭所有的视图状态。我会在后面的代码中绑定listview并使用XPath将它全部写到我的aspx页面的屏幕上。这用于搜索....下次我进行搜索时,没有出现任何新信息。原因是因为XMLDatasource默认启用了缓存。在我的情况下,我每次都在点击数据库而不需要缓存它。我关闭了数据源上的缓存,我的所有问题都得到了解决。

我只提到这个,因为我听到的错误与你的错误相同。我无法看到你是如何在itemdatabound中检索书籍的 - 而且你没有使用XML数据源的外观.....但我认为这个评论可能会为你触发一些东西。祝你好运....虽然听起来你已经开始了: - )。

答案 5 :(得分:0)

复选框控件是ReadOnly = true还是Enabled = false?

我遇到了控件的问题,无论我如何尝试在后面的代码中处理控件,上面设置的其中一个属性都没有更新。我认为禁用viewstate也会绕过ASP.NET的那个小“功能”,但它值得一试。

此外,如果通过客户端代码对项目进行排序,那么在回发中是否保留了该顺序?我不认为您可以通过javascript更改会话中的CLR对象。

答案 6 :(得分:0)

不确定这是否有帮助,请替换&lt;%#Eval(“ProjectAbbrev”)%&gt;使用OnQueueRepeater_ItemDataBound方法中指定的Hyperlink.Text查看是否所有行都已正确填充。

这可能无法解决您的问题,但了解结果会很有趣。