Reputation: 5278
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);
}
}
}
}
Upvotes: 0
Views: 4178
Reputation: 3812
You can try setting the background and foreground color in the CellFormatting
event.
void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
TrackedSet set = this._setLogBindingSource[e.RowIndex] as TrackedSet;
if (set.IsFlagged)
{
e.CellStyle.BackColor = Color.Blue;
e.CellStyle.ForeColor = Color.White;
}
else if (set.IsError)
{
e.CellStyle.BackColor = Color.Red;
e.CellStyle.ForeColor = Color.Blue;
}
}
To have your custom gradiant background you would probably still need to do that in the RowPrePaint
event, but try setting the ForeColor
in the CellFormatting
event.
You could also try setting the DefaultCellStyle
on 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 the RowTemplate
. 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.
Upvotes: 1