1
votes

I have DataGridView on my form application. After retrieving data from a table in the database and displaying them in DataGridView, I apply a green color to some cell's BackColor of the rows if a certain condition is met. After those cells are colored green, the program makes them go through another condition, which colors the whole row's BackColor red if they fail to satisfy the condition.

However, it seems like pre-colored cells cannot be overwritten with a new color. Even if I apply the following code to color the whole row red, it only works for the cells that have not been pre-colored.

for(int i=0; i<myDataGridview.Rows.Count; i++){  
    if(/*a certain condition FAILS*/){
        myDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.Red;
    }
}

Right now, I am coloring those pre-colored cells red one by one, but this takes a lot of time and code like:

for(int i=0; i<myDataGridview.Rows.Count; i++){  
    if(/*a certain condition FAILS*/){
        //Trying to color the whole row RED, but not working
        myDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.Red;
        //Manually color the cells, which are pre-colored to green, RED
        myDataGridView.Rows[i].Cells[6].Style.BackColor = Color.Red;
        myDataGridView.Rows[i].Cells[7].Style.BackColor = Color.Red;
        ....
        myDataGridView.Rows[i].Cells[13].Style.BackColor = Color.Red;
        myDataGridView.Rows[i].Cells[16].Style.BackColor = Color.Red;
    }
}

I am wondering if there is a better way to override the backColor. Can someone please help?

Here is an example (imitation) DataGridView.

Green Cells not overridden by Red Row

Those who failed the first condition automatically get their whole row red, and that works. However, if they pass the first condition and get their "Passed1" cell colored green, and then fail the second condition, as you can see, those cells stay green. I want to color the whole row red, even overwriting the pre-colored-to-green cell to red.

2
a) explain 'precolored'! b) see here for an example of coloring cells in the CellPainting event. If you code for the full set of conditions it should suffice.TaW
If a new BackColor has been applied to a cell (meaning pre-colored), that cell's BackColor cannot be changed to another color, even if I try to color the whole row including that cell with myDataGridView.Rows[i].DefaultCellStyle.BackColorMika Jones
That would be the difference between a default and an overridden value. Use the cell.BackColor to override a default value or a previous change! Also: Try to centralize all coloring etc in the CellPainting..TaW
In the image I attached in my post, rows with ID:2, 4 and 5 cannot be fully colored to Red, and their "Passed1" cells stay green.Mika Jones
Well if you just change the cell color to green, just that cell is changed, not the whole row. Please read How to Ask and take the tourŇɏssa Pøngjǣrdenlarp

2 Answers

1
votes

Cell background colors have an order of precedence when the cell is drawn. Starting at the top, it will cascade down the list until the color is set*:

  1. Cell.Style.BackColor
  2. Row.DefaultCellStyle.BackColor
  3. DataGridView.AlternatingRowsDefaultCellStyle.BackColor
  4. DataGridView.RowsDefaultCellStyle.BackColor
  5. Column.DefaultCellStyle.BackColor
  6. DataGridView.DefaultCellStyle.BackColor

* This list is not extensive and may not include every possible BackColor accessible property.


It is likely you are doing something akin to setting Cell.Style.BackColor for cells in the Passed1 column, then the code logic you posted. Which gives results like you're seeing because Green has a higher precedence than Red where it's set:

Green Cells not overridden by Red Row

Assuming your conditions for the two Passed columns is binary (Yes or No), you can fix this by "lowering" the precedence of Green background by setting the Column.DefaultCellStyle.BackColor:

private void DataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    this.dataGridView1.Columns["Passed1"].DefaultCellStyle.BackColor = Color.Green;
    this.dataGridView1.Columns["Passed2"].DefaultCellStyle.BackColor = Color.Green;

    foreach (DataGridViewRow row in this.dataGridView1.Rows)
    {
        if (row.Cells["Passed1"].Value.ToString() == "No" || row.Cells["Passed2"].Value.ToString() == "No")
        {
            row.DefaultCellStyle.BackColor = Color.Red;
        }
    }
}

Which results in:

Green Cells overridden by Red Rows

0
votes

There is an issue with the datagridview control in that you cannot change the color of any of the cells until AFTER the form has been shown by using DefaultCellStyle property. Thus methods that run, or events that fire before Shown() is called will not change the color. That's the problem probably.May you have to create a painting method and call it before Shown().