
Figure 1: BackColor of Cell[1,1] (RowIndex = 1, ColIndex =1)

Figure 2: BackColor of Row 2 (RowIndex = 2, ColIndex = -1)
Introduction
If we want to set the row or cell backcolor in a custom DataGridView
control, we may have many methods, such as customizing the column, using DefaultCellStyle
, etc. Here, a method by way of .NET events will be introduced.
The steps include: define the CellBackColorEventArgs
class, customize the DataGridView
control with the SetCellBackColor
event, override the OnCellPainting
method, and draw the cell BackColor
if the event has been subscribed.
1. Define an EventArgs Class
public class CellBackColorEventArgs : EventArgs
{
private int m_RowIndex;
private int m_ColIndex;
private Color m_BackColor = Color.Empty;
public CellBackColorEventArgs(int row, int col)
{
m_RowIndex = row;
m_ColIndex = col;
}
public int RowIndex
{
get { return m_RowIndex; }
}
public int ColIndex
{
get { return m_ColIndex; }
}
public Color BackColor
{
get { return m_BackColor; }
set { m_BackColor = value; }
}
}
The CellBackColorEventArgs
class has two public
readonly properties: RowIndex
and ColIndex
, which are used to denote the current cell in the OnCellPainting
event of DataGridView
. The public
property BackColor
has the default value Color.Empty
denoting no BackColor
to be assigned to this cell.
2. Customize a DataGridView Control
public class CustomDataGridView : DataGridView
{
public CustomDataGridView() { }
[Description("Set cell background color, Colindex -1 denotes any col.")]
public event EventHandler<CellBackColorEventArgs> SetCellBackColor;
private void DrawCellBackColor(DataGridViewCellPaintingEventArgs e)
{
if ((e.State & DataGridViewElementStates.Selected) ==
DataGridViewElementStates.Selected)
{
base.OnCellPainting(e);
return;
}
if (this.SetCellBackColor == null)
{
base.OnCellPainting(e);
return;
}
CellBackColorEventArgs ee = new CellBackColorEventArgs
(e.RowIndex, e.ColumnIndex);
this.SetCellBackColor(this, ee);
if (ee.BackColor == Color.Empty)
{
base.OnCellPainting(e);
return;
}
using (SolidBrush fillBrush = new SolidBrush(ee.BackColor))
using (Pen gridPenColor = new Pen(this.GridColor))
{
Rectangle rect1 =
new Rectangle(e.CellBounds.Location, e.CellBounds.Size);
Rectangle rect2 =
new Rectangle(e.CellBounds.Location, e.CellBounds.Size);
rect1.X -= 1;
rect1.Y -= 1;
rect2.Width -= 1;
rect2.Height -= 1;
e.Graphics.DrawRectangle(gridPenColor, rect1);
e.Graphics.FillRectangle(fillBrush, rect2);
}
e.PaintContent(e.CellBounds);
e.Handled = true;
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
this.DrawCellBackColor(e);
}
else
{
base.OnCellPainting(e);
}
}
}
The code above has three contents:
public event EventHandler<CellBackColorEventArgs> SetCellBackColor
defines an event using generic delegate EventHandler<T>
.DrawCellBackColor
is used to draw a cell.- Overrides
OnCellPainting
and uses DrawCellBackColor
when the current cell is the data cell; that is e.RowIndex >=0
and e.ColIndex >= 0
.
Key Skills
The first skill is to capture the event SetCellBackColor
before drawing the cell, and see if it has a subscription. If the event has been subscribed, then test the return parameter (see code below), and if ee.BackColor
is not Color.Empty
which denotes the BackColor
is assigned to the current cell, draw the cell including the border, background color, and content.
if (this.SetCellBackColor == null)
{
base.OnCellPainting(e);
return;
}
CellBackColorEventArgs ee = new CellBackColorEventArgs(e.RowIndex, e.ColumnIndex);
this.SetCellBackColor(this, ee);
if (ee.BackColor == Color.Empty)
{
base.OnCellPainting(e);
return;
}
Another thing is that we can set the row or cell by using an event. If we give -1 to the col index that we want to change the BackColor
, we will set the whole row BackColor
as in the usage example below.
Using the Code
After unzipping CustomDataGridView.zip, we can double click the solution file CustomDataGridView.sln to view the test project if we have Visual Studio 2005/2008, or we can run the file CustomDataGridView.exe in the \bin folder to test the control.
The Windows application example code is shown below:
private void customDataGridView1_SetCellBackColor
(object sender, CellBackColorEventArgs e)
{
if (e.RowIndex != (int)nu_RowIndex.Value)
{
return;
}
if((int)nu_ColIndex.Value == -1)
{
e.BackColor = Color.LightCoral;
}
else if ((int)nu_ColIndex.Value == e.ColIndex)
{
e.BackColor = Color.LightCoral;
}
}
private void nu_RowIndex_ValueChanged(object sender, EventArgs e)
{
customDataGridView1.Refresh();
}
private void nu_ColIndex_ValueChanged(object sender, EventArgs e)
{
customDataGridView1.Refresh();
}
The objects nu_RowIndex
and nu_ColIndex
are NumericUpDown
controls, and nu_RowIndex.Value
is the row index we want to change BackColor
, and nu_ColIndex.Value
is the col index.
Three Usage Notes
- The row index that we want to change
BackColor
must be the same as CellBackColorEventArgs e.RowIndex
- We can set the whole row
BackColor
if the col index is -1 and the row index is equal to e.RowIndex
. - We will set the cell
BackColor
if the col index and row index are the same as e.ColIndex
and e.RowIndex
.
Conclusion
We can set the row or cell BackColor
in our custom DataGridView
control by way of .NET events, and we found this method can be applied to many other cases such as merging cells, setting a cell to be readonly, etc..
You can view the Chinese contents that I wrote at http://download.csdn.net/source/612515 (only demo and no source code).