Invalid CurrentPageIndex when deleting from DataGrid

When you have a datagrid set to Allow Paging, there is more than one page in the datagrid, and you delete the last item on a page, you will often get an error "Invalid CurrentPageIndex value. It must be >= 0 and < the PageCount". Following are two different ways to handle the problem:

The first way checks where you are and takes care of it within the DeleteCommand event handler:

Private Sub DataGrid1_DeleteCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.DeleteCommand

   ' First, put in whatever code actually deletes the record from the database

   ' Then, before ending the DeleteCommand handler, make sure that we are not
   ' deleting the last item on the highest numbered page. If it is, then set
   ' the current page to the previous page, unless we are on the only page in
   ' the datagrid, then do nothing as the error will not occur.
   If DataGrid1.CurrentPageIndex = (DataGrid1.PageCount - 1) Then
     If DataGrid1.Items.Count = 1 Then
       If DataGrid1.CurrentPageIndex > 0 Then
         DataGrid1.CurrentPageIndex -= 1
       End If
     End If
   End If

End Sub

The other way uses the PageIndexChanged event to make sure we're not outside the allowable range for CurrentPageIndex when a page is 'deleted':

Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged

  If DataGrid1.CurrentPageIndex < DataGrid1.PageCount Then
    DataGrid1.CurrentPageIndex = e.NewPageIndex
    If DataGrid1.CurrentPageIndex > 0 Then
      DataGrid1.CurrentPageIndex -= 1
    End If
  End If

End Sub


Also, you may be wondering why I have no code in place to rebind the datagrid at the end of each one of these code samples. I've found an easier way (Haven't ran into any problems with this approach) that doesn't require "Re-Bind the DataGrid" code repeated all over the place with any code that affects the datagrid, just attach a call to the re-bind code to the Page.Prerender event, and that will rebind the datagrid each time the page is posted back, but not do the rebinding until all other code is complete. (The PreRender event is the last event fired in the ASP.NET 1.0/1.1 page event order, so it's a great place to put it, most code is linked to the Page.Load event, so everything else will be done by the time PreRender fires. Note that in ASP.NET 2.0, there is a new Page.Load_Complete event that makes things even better.)

The code for this trick is simply:

    Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
        PopulateDataGrid()
    End Sub

(Create the PopulateDataGrid sub that gets data from the database (if needed) and then rebinds the datagrid to the current data. Nice and clean.
Reply
This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available in our efforts to advance understanding of environmental, political, human rights, economic, democracy, scientific, and social justice issues, etc. We believe this constitutes a 'fair use' of any such copyrighted material as provided for in section 107 of the US Copyright Law. In accordance with Title 17 U.S.C. Section 107, the material on this site is distributed without profit to those who have expressed a prior interest in receiving the included information for research and educational purposes. For more information go to: http://www.law.cornell.edu/uscode/17/107.shtml . If you wish to use copyrighted material from this site for purposes of your own that go beyond 'fair use', you must obtain permission from the copyright owner.