Wednesday, May 26, 2004

DataGrid Edits With Paging & Sorting

If you've used the ASP.NET DataGrid, then you've probably used its sorting capabilities. It's very easy: just declare the sort column name in the item template and set DataGrid.AllowSorting = true. Similarly, it's easy to turn auto-paging on by setting DataGrid.AllowPaging=true.

Things get sticky, however, when you start allowing edits within the DataGrid. After adding an EditItemTemplate to each TemplateColumn that you want to be editable, and setting the DataGrid.EditItemIndex, everything appears to be just fine. One problem is that paging during edit isn't a valuable capability for the risks (if a row on page 1 is in edit, and the user moves to page 2, what is the state of the edited row? Does the user expect that the edits have been persisted? What should happen when the user now want to edit an item on page 2?) Certainly there are cases in which paging during edits is valuable, but it generally is not worth the required coding, testing, etc., so it should be turned off during editing.

So, when entering edit mode, just set DataGrid.AllowPaging=false. Easy enough, right? Wrong! This introduces a very nasty bug. The bug occurs when the user attempts to edit a row on a page other than page 1. Your code merrily goes along setting the EditItemIndex to the value passed to your EditCommand (DataGridCommandEventArgs.Item.ItemIndex)
Your event handler would look something like this:


private void MyDataGrid_EditCommand(object source, DataGridCommandEventArgs e) {
    //...
    myDataGrid.EditItemIndex = e.Item.ItemIndex;
    myDataGrid.AllowSorting = false;
    myDataGrid.AllowPaging = false;
    BindGrid();
    //...
  }


The unfortunate effect, however, is that the item in edit will be the item at e.Item.ItemIndex of page 1! Oops!

The solution I use is to make the pagers invisible by:

    //...
    myDataGrid.PagerStyle.Visible = false;
    //...

Obviously, you need to turn visibility back on during the code for canceling or committing the edits.

As an aside, it is also important to disable sorting during edits. If EditItemIndex is 4, then the fifth item will be under edit regardless of the underlying data. So, when the underlying data changes position (as sorting would do), then the wrong item is editable. The easiest way to solve this is to disable sorting (see the AllowSorting property usage above). Otherwise, you'll have to update EditItemIndex after the sort. If paging is also involved, then you'll have even more headaches to deal with (e.g., the item under edit is on page 1; the user sorts; now the correct item to edit is on page 3. Your code has to get the user to the right grid page with the right item under edit. Not impossible, but....)


No comments: