Listview not fully updating on databind() after postback

11,007

Solution 1

out of interest, what point on the page are you databinding on? Page_Load?

Try it on OnPreRender - might help out.

Solution 2

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.

Solution 3

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.

Share:
11,007
patjbs
Author by

patjbs

Lifer

Updated on June 15, 2022

Comments

  • patjbs
    patjbs almost 2 years

    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.

    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?

    The problem is that some of 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.

    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.

    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.


    UPDATE: I have tried setting EnableViewState to false and it does not fix this. I couldn't use that tactic in any case because other parts of the page (save) rely on reading the viewstate in the end.
    UPDATE: I'm providing some code snippets in the hope that they might shed some light on this issue:

    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.

    <%@ 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!