GridView not Rebinding Properly After Postback

26,718

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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

Solution 5

Your example shows

  TestGridView.Columns.RemoveAt(0); 

but did you really mean

  TestGridView.Rows.RemoveAt(0); 

(and is this the problem?)

Share:
26,718
Jason N. Gaylord
Author by

Jason N. Gaylord

I currently spend time during the day working for biBERK, a Berkshire Hathaway Insurance Company. In my spare time, I help plan Techbash, a developer conference in the Northeastern US.

Updated on September 12, 2020

Comments

  • Jason N. Gaylord
    Jason N. Gaylord over 3 years

    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();
    }
    
  • Jason N. Gaylord
    Jason N. Gaylord over 14 years
    Yeah. Look below the sample code above: "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."
  • Jason N. Gaylord
    Jason N. Gaylord over 14 years
    Thanks, but I think I got it. Totally unrelated issue.
  • Jeff Sternal
    Jeff Sternal over 14 years
    If you explain that in a little more detail, I'll be tempted to +1 your solution. ;)
  • Trajan
    Trajan almost 8 years
    Very good explanation, but if the problem is the ViewState, the proper way to solve it is to add EnableViewState="false" to your GridView.
  • Irv Lennert
    Irv Lennert almost 7 years
    To be clear the grid's DataSourceID has to be set to null so it can be re-bound.