GridView not Rebinding Properly After Postback
Asked Answered
F

6

7

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();
}
Falsework answered 18/11, 2009 at 21:49 Comment(0)
F
0

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.

Falsework answered 20/11, 2009 at 16:44 Comment(1)
If you explain that in a little more detail, I'll be tempted to +1 your solution. ;)Pru
S
13

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.

Shimmer answered 18/8, 2010 at 14:34 Comment(2)
Very good explanation, but if the problem is the ViewState, the proper way to solve it is to add EnableViewState="false" to your GridView.Iyar
To be clear the grid's DataSourceID has to be set to null so it can be re-bound.Monochasium
F
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.

Footfall answered 18/11, 2009 at 22:6 Comment(1)
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."Falsework
D
2

Your example shows

  TestGridView.Columns.RemoveAt(0); 

but did you really mean

  TestGridView.Rows.RemoveAt(0); 

(and is this the problem?)

Dionysius answered 19/11, 2009 at 21:15 Comment(0)
O
2

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();
}
Ornithology answered 20/11, 2009 at 14:40 Comment(1)
Thanks, but I think I got it. Totally unrelated issue.Falsework
F
0

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.

Falsework answered 20/11, 2009 at 16:44 Comment(1)
If you explain that in a little more detail, I'll be tempted to +1 your solution. ;)Pru
B
0

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">
Basrhin answered 12/9, 2017 at 9:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.