I have discovered an issue with GridView pager in ASP.NET 4.5 and 4.5.1 version. Since .NET 2 - 4 I have never experienced such problem.
To the point, I have a gridview that I am populating with data in code behind like this:
protected int CurrentPage { get { return SearchResults.PageIndex + 1; } }
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
BindGrid();
}
private void BindGrid()
{
int totalRowCount = 0;
SearchResults.DataSource = GetPageData(SearchResults.PageIndex, SearchResults.PageSize, out totalRowCount);
SearchResults.VirtualItemCount = totalRowCount;
SearchResults.DataBind();
}
private IEnumerable GetPageData(int start, int count, out int totalRowCount)
{
return Membership.GetAllUsers(start, count, out totalRowCount);
}
protected void SearchResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
SearchResults.PageIndex = e.NewPageIndex;
BindGrid();
}
The problem is that if I hit the last page of GridView and I try to return to any other page, my PageIndexChanging does not fire. The problem occurs only if the last page does not have same count of records as PageSize. The behavior is that my page gets reloaded, the page of gridview is filled with empty data rows up to the PageSize. The VirtualItemCount represents correctly total ItemCount.
Markup, if you find something there:
<asp:GridView runat="server" CellPadding="0" CellSpacing="0" GridLines="None" CssClass="table table-condensed table-striped table-footer"
ID="SearchResults" AllowCustomPaging="true" AllowPaging="true" PageSize="6" OnPageIndexChanging="SearchResults_PageIndexChanging" AutoGenerateColumns="false" UseAccessibleHeader="true">
...
<PagerTemplate>
<span class="pull-left">
<strong><%= SearchResults.PageIndex * SearchResults.PageSize + 1 %></strong> - <strong><%= CurrentPage * SearchResults.PageSize %></strong>
</span>
<span class="pull-left">
Total records: <strong><%= SearchResults.VirtualItemCount %></strong>
</span>
<ul class="pagination pull-right">
<li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="First"><span class="glyphicon glyphicon-backward"></span></asp:LinkButton></li>
<li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage - 2 %>" Visible="<%# CurrentPage > 2 %>"><%= CurrentPage - 2 %> </asp:LinkButton></li>
<li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage - 1 %>" Visible="<%# CurrentPage > 1 %>"><%= CurrentPage - 1 %> </asp:LinkButton></li>
<li class="active"><a href="#"><%= CurrentPage %></a></li>
<li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage + 1 %>" Visible="<%# CurrentPage < SearchResults.PageCount %>"><%= CurrentPage + 1 %></asp:LinkButton></li>
<li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="<%# CurrentPage + 2 %>" Visible="<%# CurrentPage < SearchResults.PageCount - 1 %>"><%= CurrentPage + 2 %></asp:LinkButton></li>
<li><asp:LinkButton runat="server" CommandName="Page" CommandArgument="Last"><span class="glyphicon glyphicon-forward"></span></asp:LinkButton></li>
</ul>
</PagerTemplate>
</asp:GridView>
Thank you very much, I have been dealing with this for days. Of course I could use QueryString approach, but since I will be using a lot of tables, I would like to stick with the postback approach, if possible...
EDIT:
Simpliest workaround I found was doing a BindGrid on every Page_Load. For some reason the PageIndexChanging just not fire on last page unless LastPageSize == PageSize. Then the DataBind is not recalled in order to bind CommandArguments, hence I cannot postback correctly.
On the other hand, it is not very clear and could possibly cause issues... At least double binding = double calls to SQL for data on pagechange... Otherwise, I have no idea how to force PageIndexChanging here and seems like a new .NET issue to me.