views:

945

answers:

5

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();
}
+1  A: 

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.

Chris
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
Yeah so even in the Page_Load event it doesn't work.
Jason N. Gaylord
Updated code to show you what I'm doing.
Jason N. Gaylord
+1  A: 

Your example shows

  TestGridView.Columns.RemoveAt(0);

but did you really mean

  TestGridView.Rows.RemoveAt(0);

(and is this the problem?)

Jeff Widmer
Wow. Thanks Jeff. That helps, but it doesn't solve my issue.
Jason N. Gaylord
+1  A: 

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();
}
Jim Schubert
Nope. Still not working. Thanks though!
Jason N. Gaylord
Thanks, but I think I got it. Totally unrelated issue.
Jason N. Gaylord
A: 

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.

Jason N. Gaylord
If you explain that in a little more detail, I'll be tempted to +1 your solution. ;)
Jeff Sternal
A: 

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.

Sprintstar