Share via


DataGridView, Sorting and Paging - using DataView

I needed ability to sort as well as pagination in a data grid view for an application. There are many approaches of implementing it but we had data in memory, prefetched. I used a dataview to create sorted, then paged based on counters generated manually. Here is the code for the same, but somehow I am not satisfied with the approach as its slow on large data sets. Any ideas how to do it faster?

//Form Load add a column, which is used keeping the sorted order, and then paging.

//Add an event handler to the DatagridView Sorted event

private void PageDemoForm_Load(object sender, EventArgs e)

{

productsDataTable.Columns.Add(

"RecordIndex", typeof(int));

pageNumberTextBox.Text = currentPage.ToString();

dataGridViewControl.Sorted +=

new EventHandler(dataControl_Sorted);

SetView(currentPage);

}

//Datagridview Sorted Event handler

private void dataControl_Sorted(object sender, EventArgs e)

{

SetView(currentPage);

}

//Sort the View, refresh record indexes, then filter the view on the indexes which fall between lowbound & highBound

//here pageSize is a class level constant which can be configured as needed.

private void SetView(int pageNumber)

{

int lowBound = pageSize * (pageNumber - 1);

int highBound = pageSize * pageNumber;

string sortExpression = (dataGridViewControl.SortedColumn == null) ? string.Empty : dataGridViewControl.SortedColumn.DataPropertyName + " " + ((dataGridViewControl.SortOrder == System.Windows.Forms.SortOrder.Ascending) ? "ASC" : "DESC");

//Created a sorted view

DataView pagedView = new DataView(productsDataTable, string.Empty, sortExpression, DataViewRowState.CurrentRows);

//generate row indexes, this is a hidden column in grid.

for (int i = 0; i < pagedView.Count; i++)

{

pagedView[i][

"RecordIndex"] = i + 1;

}

//set RowFilter to get desired page records.

pagedView.RowFilter =

"RecordIndex > " + lowBound + " AND " + highBound + " >= RecordIndex";

//hid the RecordIndex column from grid

DataGridViewTextBoxColumn invisibleColumn = new DataGridViewTextBoxColumn();

invisibleColumn.Visible =

false;

invisibleColumn.DataPropertyName =

"RecordIndex";

this.dataGridViewControl.Columns.Add(invisibleColumn);

this.dataGridViewControl.DataSource = pagedView;

}

//Click event for next page button

private void NextPage(object sender, EventArgs e)

{

currentPage =

int.Parse(pageNumberTextBox.Text) + 1;

pageNumberTextBox.Text = currentPage.ToString();

SetView(currentPage);

}

//Click event for previous page button

private void PreviousPage(object sender, EventArgs e)

{

currentPage =

int.Parse(pageNumberTextBox.Text) - 1;

pageNumberTextBox.Text = currentPage.ToString();

SetView(currentPage);

}

//Click event for last page button

private void LastPage(object sender, EventArgs e)

{

currentPage =

this.productsDataTable.Rows.Count / pageSize;

int residue = this.productsDataTable.Rows.Count % pageSize;

if (residue > 0)

{

currentPage++;

}

pageNumberTextBox.Text = currentPage.ToString();

SetView(currentPage);

}

//Click event for first page button

private void FirstPage(object sender, EventArgs e)

{

currentPage = 1;

pageNumberTextBox.Text = currentPage.ToString();

SetView(currentPage);

}