GridView not Rebinding Properly After Postback

0 votes
asked Nov 18, 2009 by jason-n-gaylord

I have a GridView that has a DataSourceID pointing to an ObjectDataSource. The ObjectDataSource points to a method that returns a LINQ IQueryable by using the TypeName, SelectMethod, and SelectCountMethod properties of the ObjectDataSource control. What happens is that the data loads properly upfront. However, on postback, if I remove the rows from the GridView and try to rebind using the explicit GridView.DataBind(), it doesn't work. I know LINQ is returning the proper rowcount and such because I've called the countmethod and it returns the proper rowcount. Here's a quick example:

<asp:GridView ID="TestGridView" runat="server" PageSize="20" 
    AutoGenerateColumns="false" AllowPaging="true" 
    AllowSorting="false" DataSourceID="TestDataSource">
    <Columns>
        ...
    </Columns>
</asp:GridView>

<asp:ObjectDataSource ID="TestDataSource" runat="server" 
    EnablePaging="true" SelectCountMethod="GetDetailCount" 
    SelectMethod="GetDetails" TypeName="MyApp.PageClass" />

I've tried adding a button and adding the TestGridView.DataBind(); method to that. I've tried adding it to the Page_PreRender event. No matter what I try, it's not working.

As someone suggested below, I've tried moving it to Page_Load as well, and no go. Here's a rough example of my code:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        // Set "initial" query parameters, then ...
        BindData();
    }
}

private void BindData()
{
    // EDITED: Removed the code below since I'm not looking to delete the
    //         rows from the database, but rather get the GridView to rebind
    //         which its not.
    ////Remove all current rows from the GridView
    //int colCount = TestGridView.Rows.Count;
    //for (int x = 1; x <= colCount; x++)
    //{
    //    TestGridView.DeleteRow(x);
    //}

    // Bind GridView to the ObjectDataSource
    TestGridView.DataBind();
}

protected void RegenerateImageButton_Click(object sender, ImageClickEventArgs e)
{
    // Set "updated" query parameters, then ...
    BindData();
}

6 Answers

0 votes
answered Nov 18, 2009 by chris

Dumb idea, but have you checked the page load event with the if(!Page.IsPostBack)?

From ASP.NET Page Framework Overview :

Page_Load: During this event, you can perform a series of actions to either create your ASP.NET page for the first time or respond to client-side events that result from a post. The page and control view state have been restored prior to this event. Use the IsPostBack page property to check whether this is the first time that the page is being processed. If it is the first time, perform data binding. Also, read and update control properties.

Where as

Page_PreRender: The PreRender event is fired just before the view state is saved and the controls are rendered. You can use this event to perform any last minute operations on your controls.

In effect

Because the page framework is a stateless a and disconnected model, every time a client requests an .aspx page, many things occur during the page processing ...

So in effect, you could be doing your checking before the viewstate is being set rather than after the viewstate has been restored. The most common place to check for if(!Page.IsPostBack) is typically in the Page_Load event.

0 votes
answered Nov 19, 2009 by jeff-widmer

Your example shows

  TestGridView.Columns.RemoveAt(0); 

but did you really mean

  TestGridView.Rows.RemoveAt(0); 

(and is this the problem?)

0 votes
answered Nov 20, 2009 by jim-schubert

I had a similar problem with dynamically binding a TreeView to an XmlDataSource which changed the xml source on every postback. Setting EnableCache to false fixed it. Have you tried this? (Consider the Linq2sql object already caches, if your IQueryable is using a Linq2sql object, that is)

<asp:ObjectDataSource ID="TestDataSource" runat="server" EnableCaching="false"
    EnablePaging="true" SelectCountMethod="GetDetailCount" 
    SelectMethod="GetDetails" TypeName="MyApp.PageClass" />

if that doesn't work, try this coupled with the above:

protected override void OnPreRender(EventArgs e)
{
   base.OnPreRender(e);
   BindData();
}
0 votes
answered Nov 20, 2009 by jason-n-gaylord

After looking at the code behind a bit more, I stumbled across page property values being stored in ViewState. Once I changed it over to Session, they work.

0 votes
answered Nov 18, 2010 by sprintstar

Gridviews are not re-bound on postback, their rows are pulled back from viewstate. Resetting the gridview's DatasourceID to the object data source ID on page load (or init?) will cause the gridview to be rebound.

0 votes
answered Sep 15, 2017 by torben-frandsen

I had a similar situation in which the updated values of a row didn't show no matter how I tried to databind after updating.

The GridView was bound to an ObjectDataSource, and the problem occurred after I switched its backing object from a DataSet to an Entity Framework query

Enabling ViewState for the GridView did the trick for me, thus:

<asp:GridView ID="GridViewTransporters" PageSize="100"
runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" DataSourceID="ObjectDataSourceTransporters"
DataKeyNames="Id" EnableViewState="True">
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...