如何在DataGridView中更改行颜色

172

我想要改变datagridview中特定行的颜色。当列单元格7的值小于列单元格10的值时,该行应更改为红色。有什么建议可以实现这一点吗?

20个回答

236
你需要循环遍历datagridview中的行,然后比较每行的第7列和第10列的值。
尝试这个:
foreach (DataGridViewRow row in vendorsDataGridView.Rows) 
     if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value)) 
     {
         row.DefaultCellStyle.BackColor = Color.Red; 
     }

1
谢谢你的帮助,Ricardo。我尝试了你建议的代码,但仍然无法使其工作。你介意看一下这段代码并告诉我哪里出错了吗?我是一个初学者C#学生,我相信我只是没有正确编写比较代码。foreach (DataGridView row in vendorsDataGridView.Rows) { if (row.Cells[7].Value is < row.Cells[10].Value) { dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } }感谢你的帮助。EB - EB.
EB,我基于你提供的代码添加了新的代码。你的语法有点错误,请尝试使用我刚刚添加的代码。 - Ricardo Sanchez
2
Ricardo。我将.text更改为.value,并将DefaultCellstyle.Backcolor更改为color.red,代码运行成功!!! 感谢您的时间! - EB.

81

我刚刚在调查这个问题(所以我知道这个问题发布已经将近3年了,但也许会有帮助......),但是似乎更好的选择是将代码放在RowPrePaint事件中,这样你就不需要遍历每一行,只需要遍历那些被绘制的行(因此在处理大量数据时它会表现得更好):

附加到事件

this.dataGridView1.RowPrePaint 
    += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
        this.dataGridView1_RowPrePaint);
事件代码。
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;
    }
}

3
我很喜欢你抓住问题的本质,而不是等到所有事情都完成后再去解决。这是一种非常“创新”的方法。大多数人宁愿再次遍历每一行... - bird2920
除了速度更快外,它还能在正确的时间完成操作。我曾遇到过无法对行进行着色的问题,可能是因为我选择了错误的时间设置颜色。采用这种方法可以保证在正确的时间内实现着色。 - sanderd17
1
这个很棒。而且在排序后,它以正确的方式进行了刷新。 - macmuri
美观而高效。喜欢它! - Steven Marcus
太好了!迭代3000行并设置默认单元格样式只需要大约7秒钟。这个解决方案几乎不需要任何时间 :-) - DueGe
...但是滚动非常缓慢 :-( - DueGe

26

2
这种方法的不同之处在于将比较每个单元格,而不仅仅是一个。如果你有几百个单元格,这可能会成为性能问题。 - Ricardo Sanchez

21

我也遇到了更改文本颜色的麻烦 - 我从未看到过颜色变化。

直到我将更改文本颜色的代码添加到 DataGridViewDataBindingsComplete 事件中,之后它才有效。

我希望这会帮助遇到同样问题的人们。


在 onLoad(..) 覆盖或事件中,文本颜色不会发生变化。 DataBindingsComplete 是设置行颜色的更好选择。 - timothy

13

假设单元格中的值为整数,类似以下内容...

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

未经测试,如有错误敬请谅解。

如果您知道具体的行数,可以跳过迭代:

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

谢谢你的帮助。你的建议是我解决问题最接近的方法。但我一直收到错误提示,说“Value”在上下文中不存在或“Cells”在上下文中不存在。正在努力找出原因... - EB.
这行代码现在给我报错了:运算符“<”不能应用于类型为“object”的操作数。 - EB.
将它们转换为整数,然后。 :-) 类似这样: Convert.ToInt32(dvgr.Cells[7].Value) < Convert.ToInt32(dgvr.Cells[10].Value) - Demi

9

有些人喜欢使用PaintCellPaintingCellFormatting事件,但需要注意的是,在这些事件中更改样式会引起递归调用。如果您使用DataBindingComplete,它只会执行一次。对于CellFormatting的参数是,它仅在可见单元格上调用,因此您不必格式化非可见单元格,但是您要对它们进行多次格式化。


5
您可以根据条件逐行更改背景颜色,并在应用 DatagridViewDatasource 后调用此函数。
以下是该函数的代码。只需复制并在 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;
    }
}

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;                   
    //    }
    //}
}

3
如果您绑定到具体对象的(集合),您可以通过行的DataBoundItem属性获取该具体对象。(为了避免在单元格中检查魔术字符串并使用对象的“真实”属性)
下面是一个示例:
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;}
}       

绑定到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;
    }       

然后是事件处理程序和获取具体对象(而不是DataGridRow和/或单元格)

        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;
            }
        }

2

这是我改变绑定数据源的dataGridView颜色的解决方案:

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;
                }
            }

        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接