I have a list of objects (of type ‘TrackedSet’) that is data bound to a DataGridView. When a new row is added, I want to be able to change the row appearance based on a property of the data bound object.
I can paint a custom background of the row in the RowPrePaint event, but I’m struggling to change the forecolor for the row.
From the code below, I am changing this by constantly changing the DefaultCellStyle property for the row to a predefined cell style which has the forecolour set to what I want.
Is this right? It seems clunky and just plain wrong.
Any advice appreciated.
/// <summary>
/// Handles the drawing of each DataGridView row depending on TrackedSet error or flagged state.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void setLogDataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
if ((e.State & DataGridViewElementStates.Displayed) == DataGridViewElementStates.Displayed)
{
// Always disable normal painting of selection background and focus.
e.PaintParts &= ~(DataGridViewPaintParts.SelectionBackground |
DataGridViewPaintParts.Focus);
// Get the tracked set associated with the row being painted.
TrackedSet set = this._setLogBindingSource[e.RowIndex] as TrackedSet;
if (set.IsFlagged || set.IsError) // Row requires custom painting.
{
Color backColour1 = Color.Empty;
Color backColour2 = Color.Empty;
// Get rectangle of area to paint with custom brush.
Rectangle rowBounds = new Rectangle(
e.RowBounds.Left + 1, // Location x
e.RowBounds.Top, // Location y
this.setLogDataGridView.Columns.GetColumnsWidth(
DataGridViewElementStates.Visible) -
this.setLogDataGridView.HorizontalScrollingOffset + 1, // Width
e.RowBounds.Height); // Height
// Disable painting of backgrounds when custom painting row.
e.PaintParts &= ~(DataGridViewPaintParts.Background |
DataGridViewPaintParts.ContentBackground);
if (set.IsFlagged) // Highlight colour.
{
backColour1 = this._highlightBackColour1;
backColour2 = this._highlightBackColour2;
this.setLogDataGridView.Rows[e.RowIndex].DefaultCellStyle = this._highlightStyle;
}
else // Error colour.
{
backColour1 = this._errorBackColour1;
backColour2 = this._errorBackColour2;
this.setLogDataGridView.Rows[e.RowIndex].DefaultCellStyle = this._errorStyle;
}
// Paint the custom background.
using (Brush lgb = new LinearGradientBrush(rowBounds, backColour1, backColour2, LinearGradientMode.Vertical))
{
e.Graphics.FillRectangle(lgb, rowBounds);
}
}
}
}
You can try setting the background and foreground color in the
CellFormattingevent.To have your custom gradiant background you would probably still need to do that in the
RowPrePaintevent, but try setting theForeColorin theCellFormattingevent.You could also try setting the
DefaultCellStyleon the row right after you bind it to the DataGridView, but I believe that certain events will trigger the DefaultCellStyle to be reset back to theRowTemplate. You may be able to set the DefaultCellStyle on the RowTemplate after you bind the data to the grid so your cell style won’t be reset.