views:

4116

answers:

3

Hi,

I have an asp.net gridview that is originally bound to a sqldatasource control, but when the user presses an external button, it instead gets the contents of a datatable rather than a SQLdatasource control. I therefore had to write code in the PageIndexChanging event of the gridview to allow for paging. My code is as follows:

Protected Sub gvEvents_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles gvEvents.PageIndexChanging

gvEvents.PageIndex = e.NewPageIndex

gvEvents.DataBind()

This worked beautifully until I added an AJAX update panel so the whole page wouldn't postback every time it paged, and paging stopped working. I debugged it and discovered that it is actually calling the PageIndexChanging event, but nothing is happening.

I searched the web and found a few people with the same problem, but their solutions did not work for me. There was one on this site whose problem was solved by the following:

In PageIndexchanging event, where you bind data to grid, make sure, data is again fetched from the DB

I don't know what that means; my data was being bound as demonstrated above. I have "enable paging" set to true and EnableSortingAndPagingCallbacks set to false.

I would really appreciate if someone can help me. I am including my markup for the updatepanel below. Thank you so much!

`

    <ContentTemplate>

             <asp:GridView ID="gvEvents" runat="server"  DataKeyNames = "intID"
    AutoGenerateColumns="False" AllowPaging="True" GridLines="None" CellPadding="10" 
                 ForeColor="#333333" PageSize="6" DataSourceID="defaultDS" >
                 <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />

            <Columns>
            <asp:TemplateField HeaderText="Date">
                   <ItemTemplate>
                    <!-- put code block inside label? To set the formatter to include year if 
                    it's next year? -->
                    <asp:Label ID="Label1" runat="server" 
                        Text = '<%# RepeatingMethods.DetermineOngoing(CType(Eval("dtmEventStartDate"), DateTime) , CType(Eval("dtmEventEndDate"), DateTime))%>'> </asp:Label>

                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField>
              <ItemTemplate>
              <asp:Label ID="Label4" runat="server" Text='<%# Eval("chvAgeRange")  %>'> </asp:Label> <br />
               <asp:Label ID="Label3" runat="server" Text= '<%# Eval("chvState")  %>'> </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:HyperLinkField DataNavigateUrlFields="intId" 
                DataNavigateUrlFormatString="EventDetail.aspx?intId={0}" 
                DataTextField="chvEventName" />

                <asp:BoundField DataField="chvBriefDescription" HeaderText="Description" 
                    SortExpression="chvBriefDescription" />


        </Columns>
                 <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
                 <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
                 <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
                 <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
                 <AlternatingRowStyle BackColor="White" />

            <asp:Label ID="lblError" runat="server"></asp:Label>

<br />
</ContentTemplate>
</asp:UpdatePanel>`
A: 

In PageIndexchanging event, where you bind data to grid, make sure, data is again fetched from the DB I don't know what that means; my data was being bound as demonstrated above.

It means that you need to fetch your data again in your code behind page. You are using a SQLdatasource in your design/html page, so you need to remove that and use a SQL Connection, SQL Command, etc. to fetch your data and then set that as your control's datasource.

Something like below:

http://www.aspnettutorials.com/tutorials/database/db-grid-aspnet2-vb.aspx

Your code should look something like this

Protected Sub Page_Load(...)
   gvEvents.PageIndex = 0
   LoadData();// loads initial data
end sub

private sub LoadData()
 '' do your SQL Conn and Command here
 '' set your datasource of gridview here
end sub

Protected Sub gvEvents_PageIndexChanging(...) Handles gvEvents.PageIndexChanging
  gvEvents.PageIndex = e.NewPageIndex
  LoadData()
  gvEvents.DataBind()
end sub
Jim W
I'm sorry if I didn't make myself clear. I am using SQL connections and commands to fetch my data - my datasource for the gridview is a datatable. My problem is that my custom paging code worked fine until I put it into an update panel, and now it doesn't. Why would I suddenly need to re-fetch my data from the database?
bsg
Because the data from your db isn't persistently stored in your gridview/page. When you do a postback inside of an update panel, you need to fetch the records again so you can load it to the gridview because at that moment, there is no data in your datasource.
Jim W
Updated my original post to include sample code
Jim W
Thank you very much. So you're saying that I need to go back to the database and rerun all my select commands every time I want to fetch a new page? Why don't I have to do that outside of the update panel?
bsg
Yes that's what I'm saying. I think it's because when you set the datasource and it's rendered, then it only saves the items that you see (current page) to the view state, so on other post backs, it just renders whats in the control's view state. But if you change page index, then it needs to get the items on whatever page index is the new index so it can store the new list of items to the view state.
Jim W
Thank you very much. I did as you suggested and it works! I really appreciate all your help.
bsg
A: 

Controls that Are Not Compatible with UpdatePanel Controls

The following ASP.NET controls are not compatible with partial-page updates, and are therefore not supported inside an UpdatePanel control:

GridView and DetailsView controls when their EnableSortingAndPagingCallbacks property is set to true. The default is false.

http://www.asp.net/Ajax/Documentation/Live/overview/UpdatePanelOverview.aspx

rick schott
+1  A: 

Just update the AJAX Panel after databind().

assume id of the Update Panel is AJAXPanel

Protected Sub gvEvents_PageIndexChanging(...) Handles gvEvents.PageIndexChanging             
     gvEvents.PageIndex = e.NewPageIndex
     LoadData()
     gvEvents.DataBind()
     // The below line refreshes the update panel..  
     AJAXPanel.Update()
end sub
venkatx5