5

I have a gridview that has its DataSourceID property set to a custom ObjectDataSource object. When AllowPaging is set to True, the GridView disappears after a postback. If I set AllowPaging to False it's fine. Can someone shed some light on this for me? :)

Edit: The other thing I'm confused about is I thought that if you set the DataSourceID that the grid would get data from the datasource whenever it needed it. If the grid is disappearing because it's not holding the data, why isn't the gridview getting the data it needs from the datasource?

adam0101
  • 29,096
  • 21
  • 96
  • 174

2 Answers2

4

It's possible that after the postback occurs the datasource is not being maintained or refilled and there are no items to populate the grid. Are you handling state correctly for the datasource object (rebinding/keeping the source alive) when paging is enabled?

This may sound like a vague answer, but without an example of how the source is getting the data it's kind of hard to diagnose why the items would be gone.

Edit:
The method I was thinking of was for callback paging/sorting. However I did find some info ont he ODS & Paging.. make sure you have set the following:

  1. GridView: AllowPaging and off course you need to set PageSize.
  2. ObjectDataSource: EnablePaging, also you need to set the:
    • MaximumRowsParameterName="maxRows"
    • StartRowIndexParameterName="startRowIndex"
    • SelectCountMethod="RecordCount"

I think you only need to set the 3 sub items of item 2 if you want to handle paging size etc manually.

Then you can read more up on this here.

Quintin Robinson
  • 81,193
  • 14
  • 123
  • 132
  • When AllowPaging is False I thought the grid doesn't rebind, it just grabs the values from viewstate. Are you saying I have to bind the data to the gridview on every postback when paging is enabled even if I'm not going to a different page? I'm just clicking a button on the page. – adam0101 Feb 24 '09 at 23:04
  • I think there is a way to make the grid handle paging on it's own if binding to a datasource via an id but there is a property that you must set, although I may be thinking of "callback" paging. Let me check into it. Otherwise yes you generally have to handle paging manually. – Quintin Robinson Feb 24 '09 at 23:10
  • After reading this: http://blog.tylerholmes.com/2008/06/datasource-vs-datasourceid-internals.html it sounded like simply setting the DataSourceID was the trigger to get the grid to databind itself whenever it needed data. – adam0101 Feb 24 '09 at 23:14
  • Your last edit got me looking some more - especially the 3rd bullet. It turns out my custom datasource was returning zero for the record count. So even though the data doesn't get rebound each time, it must still look at the count on each postback. I fixed it and got it working! Thanks for your help – adam0101 Feb 25 '09 at 23:58
  • No problem, glad you got it up and running! – Quintin Robinson Feb 26 '09 at 00:35
0

To answer more of @adam0101's response, what I think he means by "...It turns out my custom datasource was returning zero for the record count.", is that you may need to "re-attach" the datasource to the gridview. ASP.net automatically knows you're retriving record-'n', where 'n' is the next first row of the next page. This solution is more for cases where you don't want to allow asp.net to automatically handle data in your gridview, perhaps due to wanting to load data after another event (a LOAD DATA button for example), and not when the page has loaded for the first time. But as Adam mentioned below the real reason was he "...had created a datasource subclass that inherited ObjectDataSource, but it was implemented incorrectly.". Sorry for my assumption there Adam. Thanks

However, the rest of my solution I think will work for those stuck on using manually derived data sources.

ie

Set your GridView as per above, and note - without a DataSource property! Here is my example:

     <asp:GridView ID="gvStudents" DataKeyNames="StudentID" runat="server" 
            ShowFooter="True" AutoGenerateColumns="False" Width="100%" AllowSorting="True" AllowPaging="true" PageSize="10" OnPageIndexChanging="gvStudents_PageIndexChanging">

Next make a private method or routine that you can call upon when ever you need to force the gridview onto a new page.

private void BindGridViewServer(GridView gv1)
{
    gv1.DataSource = sdsStudents;   //re-attach the datasource
    gv1.DataBind();                 //get a page of data AllowPaging must be true
}

Next, create the OnPageIndexChanging method:

protected void gvStudents_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView myGV = (GridView)sender;
    myGV.PageIndex = e.NewPageIndex;
    BindGridViewServer(myGV);
}

For the sake of completing this answer, here is my code where I load the data when I want - not when a PostPack is fired, which is the default...

    protected void btnSEARCH(object sender, EventArgs e)
        {
//some code
                    //bind the gridview to the datasource here and then bind!
                    gvStudents.DataSource = sdsStudents;
                    gvStudents.DataBind();
//more code etc
        }
Fandango68
  • 4,461
  • 4
  • 39
  • 74
  • 1
    Actually, that's not true. What I meant by my response was that I had created a datasource subclass that inherited ObjectDataSource, but it was implemented incorrectly so that the record count was literally returning zero. The rest of your answer might be true, I don't know - thankfully I haven't had to work with WebForms for years, but that was the actual meaning of my comment. – adam0101 Aug 26 '15 at 14:12
  • Kudos to you Adam. Thanks. I have updated my response. – Fandango68 Aug 26 '15 at 23:41