How to change row color in datagridview
Asked Answered
H

20

175

I would like to change the color of a particular row in my datagridview. The row should be changed to red when the value of columncell 7 is less than the value in columncell 10. Any suggestions on how to accomplish this?

Hand answered 3/2, 2010 at 3:0 Comment(0)
M
238

You need to loop through the rows in the datagridview and then compare values of columns 7 and 10 on each row.

Try this:

foreach (DataGridViewRow row in vendorsDataGridView.Rows) 
     if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value)) 
     {
         row.DefaultCellStyle.BackColor = Color.Red; 
     }
Markettamarkey answered 3/2, 2010 at 15:25 Comment(3)
Thank you for the help Ricardo. I have tried the code you suggested. I still can't get it to work. Would you mind taking a look at this code and tell me where I've gone wrong? I am a beginning C# student. I'm sure I just haven't written the comparison code correctly. foreach (DataGridView row in vendorsDataGridView.Rows) { if (row.Cells[7].Value is < row.Cells[10].Value) { dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } I appreciate your help. EBHand
EB I added new code based in the code you provided. Your sintax was off a little bit, try the code I just added above.Markettamarkey
Ricardo. I changed .text to .value and changed to DefaultCellstyle.Backcolor = color.red and the code worked!!! Thank you for your time! EBHand
D
87

I was just investigating this issue (so I know this question was published almost 3 years ago, but maybe it will help someone... ) but it seems that a better option is to place the code inside the RowPrePaint event so that you don't have to traverse every row, only those that get painted (so it will perform much better on large amount of data:

Attach to the event

this.dataGridView1.RowPrePaint 
    += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
        this.dataGridView1_RowPrePaint);

The event code

private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
    if (Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[7].Text) < Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[10].Text)) 
    {
        dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
    }
}
Darkle answered 21/10, 2012 at 14:1 Comment(7)
I really like how you catch the problem at the root instead of waiting until after everything has been painted. This is a very "outside the box" approach. Most people would rather just loop through every row again...Czardas
Next to being much faster, it also helps doing it at the right time. I had issues with my rows not getting colored, probably because I set the color at the wrong time. With this approach, it's guaranteed to happen at the correct time.Germin
This works geat. Also after sorting its refreshing in correct way.Yawmeter
Beautiful and efficient. Love it!Bronchiole
Excellent ! Iterating 3000 rows and setting default cell style takes ~7 seconds. This solution takes almost nothing :-)Garvy
... but scrolling very slow :-(Garvy
@Garvy I didn't have any performance issues when scrolling with this solution even though I have several thousand rows in my table.Chema
N
27

You're looking for the CellFormatting event.
Here is an example.

Nyaya answered 3/2, 2010 at 3:2 Comment(1)
The difference with this approach is that every single cell will be compared as opposed to just one. It might be a performance problem if you have several hundred cells.Markettamarkey
F
21

I had trouble changing the text color as well - I never saw the color change.

Until I added the code to change the text color to the event DataBindingsComplete for DataGridView. After that it worked.

I hope this will help people who face the same problem.

Freezing answered 26/11, 2012 at 7:52 Comment(1)
text coulour doesnt change when in onLoad(..) override or the event. DataBindingsComplete is much better place to do the colour setting of rows.Helfand
H
13

Something like the following... assuming the values in the cells are Integers.

foreach (DataGridViewRow dgvr in myDGV.Rows)
{
  if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
  {
    dgvr.DefaultCellStyle.ForeColor = Color.Red;
  }
}

untested, so apologies for any error.

If you know the particular row, you can skip the iteration:

if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
  dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
Headrest answered 3/2, 2010 at 4:4 Comment(3)
Thank you for your help. Your suggestion is the closest I've gotten to solving the problem. But I keep getting the error saying either "Value" doesn't exist in context or "Cells" doesn't exist in context. Trying to figure it out...Hand
this line of code (dgvr.Cells[7].Value < dgvr.Cells[10].Value) now gives me this error Operator '<' cannot be applied to operands of type 'object' and 'object'Hand
Cast them to Integer, then. :-) something like: Convert.ToInt32(dvgr.Cells[7].Value) < Convert.ToInt32(dgvr.Cells[10].Value)Headrest
M
9

Some people like to use the Paint, CellPainting or CellFormatting events, but note that changing a style in these events causes recursive calls. If you use DataBindingComplete it will execute only once. The argument for CellFormatting is that it is called only on visible cells, so you don't have to format non-visible cells, but you format them multiple times.

Microsurgery answered 25/2, 2013 at 19:50 Comment(0)
A
5

You can Change Backcolor row by row using your condition.and this function call after applying Datasource of DatagridView.

Here Is the function for that. Simply copy that and put it after Databind

private void ChangeRowColor()
{
    for (int i = 0; i < gvItem.Rows.Count; i++)
    {
        if (BindList[i].MainID == 0 && !BindList[i].SchemeID.HasValue)
            gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#C9CADD");
        else if (BindList[i].MainID > 0 && !BindList[i].SchemeID.HasValue)
            gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#DDC9C9");
        else if (BindList[i].MainID > 0)
            gvItem.Rows[i].DefaultCellStyle.BackColor = ColorTranslator.FromHtml("#D5E8D7");
        else
            gvItem.Rows[i].DefaultCellStyle.BackColor = Color.White;
    }
}
Aerobe answered 1/10, 2014 at 11:17 Comment(0)
B
3
private void dtGrdVwRFIDTags_DataSourceChanged(object sender, EventArgs e)
{
    dtGrdVwRFIDTags.Refresh();
    this.dtGrdVwRFIDTags.Columns[1].Visible = false;

    foreach (DataGridViewRow row in this.dtGrdVwRFIDTags.Rows)
    {
        if (row.Cells["TagStatus"].Value != null 
            && row.Cells["TagStatus"].Value.ToString() == "Lost" 
            || row.Cells["TagStatus"].Value != null 
            && row.Cells["TagStatus"].Value.ToString() == "Damaged" 
            || row.Cells["TagStatus"].Value != null 
            && row.Cells["TagStatus"].Value.ToString() == "Discarded")
        {
            row.DefaultCellStyle.BackColor = Color.LightGray;
            row.DefaultCellStyle.Font = new Font("Tahoma", 8, FontStyle.Bold);
        }
        else
        {
            row.DefaultCellStyle.BackColor = Color.Ivory;
        }
    }  

    //for (int i= 0 ; i<dtGrdVwRFIDTags.Rows.Count - 1; i++)
    //{
    //    if (dtGrdVwRFIDTags.Rows[i].Cells[3].Value.ToString() == "Damaged")
    //    {
    //        dtGrdVwRFIDTags.Rows[i].Cells["TagStatus"].Style.BackColor = Color.Red;                   
    //    }
    //}
}
Boeotian answered 3/12, 2010 at 11:34 Comment(0)
R
3

If you bind to a (collection) of concrete objects, you can get the that concrete object via the DataBoundItem property of the row. (To avoid check for magic strings in the cell and using "real" properties of the object)

Skeleton example below:

DTO/POCO

public class Employee
{
    public int EmployeeKey {get;set;}

    public string LastName {get;set;}

    public string FirstName {get;set;}

    public bool IsActive {get;set;}
}       

Binding to the datagridview

    private void BindData(ICollection<Employee> emps)
    {
        System.ComponentModel.BindingList<Employee> bindList = new System.ComponentModel.BindingList<Employee>(emps.OrderBy(emp => emp.LastName).ThenBy(emp => emp.FirstName).ToList());
        this.dgvMyDataGridView.DataSource = bindList;
    }       

then the event handler and getting the concrete object (instead of a DataGridRow and/or cells)

        private void dgvMyDataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            Employee concreteSelectedRowItem = this.dgvMyDataGridView.Rows[e.RowIndex].DataBoundItem as Employee;
            if (null != concreteSelectedRowItem && !concreteSelectedRowItem.IsActive)
            {
                dgvMyDataGridView.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.LightGray;
            }
        }
Rhaetic answered 25/4, 2017 at 15:51 Comment(0)
B
2

This is my solution to change color to dataGridView with bindingDataSource:

private void dataGridViewECO_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{            

    if (e.ListChangedType != ListChangedType.ItemDeleted)
    {

        DataGridViewCellStyle green = this.dataGridViewECO.DefaultCellStyle.Clone();
        green.BackColor = Color.Green;

        DataGridViewCellStyle gray = this.dataGridViewECO.DefaultCellStyle.Clone();
        gray.BackColor = Color.LightGray;



        foreach (DataGridViewRow r in this.dataGridViewECO.Rows)
        {

            if (r.Cells[8].Value != null)
            {

                String stato = r.Cells[8].Value.ToString();


                if (!" Open ".Equals(stato))
                {
                    r.DefaultCellStyle = gray;
                }
                else
                {
                    r.DefaultCellStyle = green;
                }
            }

        }

    }
}
Brobdingnagian answered 7/10, 2015 at 7:42 Comment(0)
R
0

I typically Like to use the GridView.RowDataBound Event event for this.

protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.ForeColor = System.Drawing.Color.Red;
    }
}
Riana answered 4/2, 2010 at 2:49 Comment(1)
He is asked for DatagridView in Window Application. And your answer is about GridView of Web.Aerobe
S
0

Works on Visual Studio 2010. (I tried it and it works!) It will paint your entire row.

  1. Create a button for the datagridview.
  2. Create a CellClick event and put the next line of code inside of it.

if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)    
{
    dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
Shaer answered 29/10, 2014 at 13:53 Comment(0)
P
0

You have not mentioned how value is changed. I have used similar functionality when user is entering value. i.e. entering and leaving edit mode.

Using CellEndEdit event of datagridview.

private void dgMapTable_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    double newInteger;

    if (double.TryParse(dgMapTable[e.ColumnIndex,e.RowIndex].Value.ToString(), out newInteger)
    {
        if (newInteger < 0 || newInteger > 50)
        {
            dgMapTable[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Red; 

            dgMapTable[e.ColumnIndex, e.RowIndex].ErrorText 
                = "Keep value in Range:" + "0 to " + "50";
        }
    }                               
}

You may add logic for clearing error notification in a similar way.

if in your case, if data is loaded programmatically, then CellLeave event can be used with same code.

Pretypify answered 19/12, 2014 at 7:2 Comment(0)
F
0

With this code, you only change rows backcolor where columname value is null other rows color still the default one.

       foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells["columnname"].Value != null)
                    {
                        dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
                    }
                 }
Fallon answered 30/8, 2016 at 13:12 Comment(0)
N
0

Just a note about setting DefaultCellStyle.BackColor...you can't set it to any transparent value except Color.Empty. That's the default value. That falsely implies (to me, anyway) that transparent colors are OK. They're not. Every row I set to a transparent color just draws the color of selected-rows.

I spent entirely too much time beating my head against the wall over this issue.

Nedra answered 2/2, 2017 at 22:34 Comment(0)
I
0
int counter = gridEstimateSales.Rows.Count;

for (int i = 0; i < counter; i++)
{
    if (i == counter-1)
    {
        //this is where your LAST LINE code goes
        //row.DefaultCellStyle.BackColor = Color.Yellow;
        gridEstimateSales.Rows[i].DefaultCellStyle.BackColor = Color.Red;
    }
    else
    {
        //this is your normal code NOT LAST LINE
        //row.DefaultCellStyle.BackColor = Color.Red;
        gridEstimateSales.Rows[i].DefaultCellStyle.BackColor = Color.White;
    }
}
Indentation answered 17/8, 2017 at 9:2 Comment(0)
G
0

I landed here looking for a solution for the case where I dont use data binding. Nothing worked for me but I got it in the end with:

dataGridView.Columns.Clear(); 
dataGridView.Rows.Clear();
dataGridView.Refresh();
Getter answered 8/6, 2018 at 2:12 Comment(0)
H
0

If you are the second dumbest developer on the planet (me being the dumbest), all of the above solutions seem to work: CellFormatting, DataSourceChanged, and RowPrePaint. I prefer RowPrePaint.

I struggled with this (for way too long) because I needed to override my SelectionBackColor and SelectionForeColor instead of BackColor and ForeColor as I was changing the selected row.

Harm answered 6/3, 2020 at 20:42 Comment(0)
H
0
dataGridView1.Rows[1].Cells[1].Style.BackColor = Color.Yellow;


    
Hellish answered 14/3, 2021 at 15:58 Comment(0)
P
0

if (this.dgblista.Columns[e.ColumnIndex].Name == "TOTAL PAGADO") { if ((dgblista.Columns[e.ColumnIndex].Name == "COSTO DEL CURSO") == (dgblista.Columns[e.ColumnIndex].Name == "TOTAL PAGADO")) { e.CellStyle.ForeColor = Color.White; e.CellStyle.BackColor = Color.Red; } }

Proposition answered 15/7, 2022 at 20:26 Comment(1)
I don't know if your answer is correct or at least useful, but you should at least format it a little bit. Use four blanks at the beginning of your code and it will be automatically formatted as a code section. Just a hint for a newbie.Tenerife

© 2022 - 2024 — McMap. All rights reserved.