views:

2293

answers:

7

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!

A: 

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.

CB
disabling the viewstate does not solve the problem, unfortunately.
patjbs
A: 

Maybe your QueueListView is getting re-bound for some reason.

Try resetting the DataSource value after the DataBind() to see what happens

QueueListView.DataBind();
QueueListView.DataSource = null;
Christian Hagelid
thanks for the thought but unfortunately no luck there
patjbs
A: 

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.

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 :-).

A: 

Is the checkbox control ReadOnly=true or 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.

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.

Drithyin
Not set to read only, and the problem occurs both for users for whom the checkboxes are enabled, and those for whom they are not. Interesting idea though that I might look at. As for the client side sorting, performing a resort fires off a callback function which keeps the server session data up to date with what the client is seeing.
patjbs
+2  A: 

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

Try it on OnPreRender - might help out.

tim
Thanks tim! I've pretty much moved on from this, but if I run into this issue again, I'll be sure to give that a shot.
patjbs
Tim is right - I had the exact same problem and Page_PreRender works on postbacks :)
Jason
A: 

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.

This probably won't solve your problem, but will be interesting to know the result.

o.k.w
That field was actually rendering correctly in the code shown above. It was the checkboxes and dropdowns (not shown) that failed to properly resort/redraw along with the rest of the display.
patjbs
Yea I got what you meant. Btw, didn't see any dropdowns in your code, how was the databinding done?Try render just text/label for the checkboxes and dropdowns without the controls. See if the values are rendered.
o.k.w
A: 

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.

awe