DataGrid Customization Part-II: Custom Sorting and DataGrid Column Hiding


In DataGrid Customization Part 1, I covered the following topics:

  • How to I get the name and index of the Column headers?
  • How do I find out if mouse click right click was on a column header?
  • How do I get the row and column numbers of current selected cell?
  • How to change the positions of columns?

Here I will add more functionality to the same application.

In this article, I am going to cover two key topics. First, how to implement custom sorting and second how to hide or remove a DataGrid columns by removing on the column header.

When you will run the application and right mouse click on the DataGrid column header, you will see a pop up menu with three items - Sort Ascending, Sort Descending, and Remove Column and so on.

Adding a context menu to a Windows application is pretty simple. Just drag a ContextMenu from Toolbox to the form and add three items as shown in Figure 1.

Now you can write the click event handlers for these menus by simply double clicking on the menu items. This is where we will write our code to sort and hide DataGrid columns.

First of all, we need to add some variables to the application. The best bet for you is to download the source code and browse its contents. The variables are listed as following:

// Developer defined variables
private OleDbConnection conn = null;
private string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb";
private string sql = null;
private DataSet ds = null;
private string colHeadName = null;
private DataGridColumnStyle dcStyle = null;
private DataView dtView = null;
private System.Windows.Forms.ContextMenu columnHeadMenu;
private OleDbDataAdapter adapter = null;

The FillDataGrid method fills data to the DataGrid from Northwind database. This method is listed in the following listing. As you can see from this code, I also create a DataView object called dtView, which will be used in sorting.

Note: Actually you can also read sorted data by using a SELECT.. FROM ...ORDER BY SQL statement but you need to load data from database every time you want to sort the data, which makes application slower but is advisable in a multi-user and real-time data processing environments. In simple client server or desktop applications, when there is no other user modifying data, this approach is advisable.

private void FillDataGrid()
{
sql = "SELECT * FROM Customers";
conn =
new OleDbConnection(connectionString);
adapter =
new OleDbDataAdapter(sql, conn);
ds =
new DataSet("Customers");
adapter.Fill(ds, "Customers");
dtView = ds.Tables[0].DefaultView;
dataGrid1.DataSource = dtView;
// By default there is no DataGridTableStyle object.
// Add all DataSet table's style to the DataGrid
foreach(DataTable dTable in ds.Tables)
{
DataGridTableStyle dgStyle =
new DataGridTableStyle();
dgStyle.MappingName = dTable.TableName;
dataGrid1.TableStyles.Add(dgStyle);
}
// DataGrid settings
dataGrid1.CaptionText = "DataGrid Customization";
dataGrid1.HeaderFont =
new Font("Verdana", 12);
}

Now next step is to load the context menu when a user right clicks on the DataGrid column header. To do so, you can write the code on the DataGrid's mouse down event. The following code does the trick for you. As you can see from this code, I set dataGrid1.ContextMenu = columnHeadMenu, where columnHeadMenu is the name of the context menu you added in the previous step. After adding the context menu, A get the DataGridColumnStyle of the current column, which will be used when you want to hide the column.

string
str = null;
Point pt =
new Point(e.X, e.Y);
DataGrid.HitTestInfo hti = dataGrid1.HitTest(pt);
// If right mouse button clicked
if(e.Button == MouseButtons.Right)
{
if(hti.Type == DataGrid.HitTestType.ColumnHeader)
{
dataGrid1.ContextMenu = columnHeadMenu;
DataGridTableStyle gridStyle = dataGrid1.TableStyles["Customers"];
colHeadName = gridStyle.GridColumnStyles[hti.Column].MappingName.ToString();
dcStyle = gridStyle.GridColumnStyles[hti.Column];
}
}

The following code sorts data based on the menu item click. As you can see from the code, sorting is pretty simple. I just set the Sort property of DataView and calls DataGrid's Refresh method.

private void SortAscMenu_Click(object sender, System.EventArgs e)
{
if(! colHeadName.Equals(string.Empty))
{
dtView.Sort = colHeadName + " ASC";
dataGrid1.Refresh();
}
}
private void SortDescMenu_Click(object sender, System.EventArgs e)
{
if(! colHeadName.Equals(string.Empty))
{
dtView.Sort = colHeadName + " DESC";
dataGrid1.Refresh();
}
}

Now last step left is Column hiding. The simplest way to hide or remove a column of a DataGrid by setting a column's width to 0. The following code is written on the Remove Column menu item event handler.

private void RemoveColMenu_Click(object sender, System.EventArgs e)
{
dcStyle.Width = 0;
}

Just download the source code, right click on the DataGrid's Column header and select any menu item and see the code in action.

I will be back with more tips and tricks.

Cheers!


Similar Articles
Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.