Implementing a transparent row selection in a DataGridView control

During a recent project I was involved in, I had to implement a transparent row selection for the DataGridView control in a Winforms C# 2.0 application. This meant that instead of getting the usual dark blue color (SystemColors.Highlight) for each cell of the selected row to paint only a certain cell as dark blue and a dark blue border around the visible part of the row, the rest of the cells having to keep their already set colors.

The first thing that we need to take care in the grid view control in case we want to have a row selection is to set the SelectionMode property of the grid control to FullRowSelect. This will make sure that each time we select one cell, the entire row will be selected.

full_row_select 

Once we complete this step we should start working on the actual “transparent” selection. In order to customize the look of the cells we need to implement the CellFormatting event of the DataGridView control and to change the way the cell looks when it’s selected we can customize two properties: SelectionBackColor (to change the background color of the cell in the selected state) and SelectionForeColor (to handle the color of the text in the cell in the selected state).

In order to have the first cell selected normally and the rest of the cells in the row to have the “transparent” selection look I used the following code for the CellFormatting event:

Code Snippet
  1. private void musicGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
  2.         {
  3.             // for the first cell paint paint the background as highlight and text as white in case of selection
  4.             if (e.ColumnIndex == 0)
  5.             {
  6.                 e.CellStyle.SelectionBackColor = SystemColors.Highlight;
  7.                 e.CellStyle.SelectionForeColor = Color.White;
  8.             }
  9.             else
  10.             {
  11.                 e.CellStyle.SelectionBackColor = e.CellStyle.BackColor;
  12.                 e.CellStyle.SelectionForeColor = e.CellStyle.ForeColor;
  13.             }
  14.         }

 

If we run the application after this step well get something like the following screenshot:

selection_no_border

This looks fine, but it’s not enough – this looks like we would have cell level selection allowed only for the first column. This would look much better if we would paint a border around the selected row, to make it clear which row is selected and what type of selection mode we have. To achieve this I implemented the RowPostPaint event and used the following piece of code to draw a rectangle around my selected row:

Code Snippet
  1. private void musicGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
  2.         {
  3.             var dgv = (DataGridView)sender;
  4.             // run this piece of code only for the selected row
  5.             if (dgv.Rows[e.RowIndex].Selected)
  6.             {
  7.                 int width = musicGridView.Width;
  8.                 Rectangle r = dgv.GetRowDisplayRectangle(e.RowIndex, false);
  9.                 var rect = new Rectangle(r.X, r.Y, width – 1, r.Height – 1);
  10.                 // draw the border around the selected row using the highlight color and using a border width of 2
  11.                 ControlPaint.DrawBorder(e.Graphics, rect,
  12.                     SystemColors.Highlight, 2, ButtonBorderStyle.Solid,
  13.                     SystemColors.Highlight, 2, ButtonBorderStyle.Solid,
  14.                     SystemColors.Highlight, 2, ButtonBorderStyle.Solid,
  15.                     SystemColors.Highlight, 2, ButtonBorderStyle.Solid);
  16.             }
  17.         }

 

Once we implement this event for our grid view we’ll reach the result we wanted:

transparent_selection

This way of selecting a row in a DataGridView control can be very useful in case in the CellFormatting event we implement some logic to paint certain cell in some specific way based on some business logic. For example a red background for a cell in case of an error for that grid entry and so on… Such formatting would not be visible in case of the row beiong selected and we having left the default row selection implementation.

Implementing such a selection is not a very difficult task, but if you are not very familiar with the DataGridView control it can be tricky to know where and how to implement this. Hope this short article will be useful for other people as well.