如何更改datagridview中的行颜色?


143

我想在我的datagridview中更改特定行的颜色。当列单元格7的值小于列单元格10中的值时,应将行更改为红色。

Answers:


192

您需要遍历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
谢谢里卡多的帮助。我已经尝试过您建议的代码。我仍然无法正常工作。您介意看一下这段代码,并告诉我哪里出错了吗?我是C#的入门生。我确定我只是没有正确编写比较代码。foreach(vendorDataGridView.Rows中的DataGridView行){如果(row.Cells [7] .Value是<row.Cells [10] .Value){dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } 我感谢您的帮助。EB
EB。

EB我根据您提供的代码添加了新代码。您的sintax有点偏离,请尝试上面刚刚添加的代码。
里卡多·桑切斯

2
里卡多 我将.text更改为.value,并更改为DefaultCellstyle.Backcolor = color.red,并且代码正常工作!!!感谢您的时间!EB
EB。

60

我只是在调查这个问题(所以我知道这个问题大约在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

24

您正在寻找CellFormatting活动。
是一个例子。


2
这种方法的区别在于,将比较每个单个单元格,而不只是一个。如果您有数百个单元,则可能是性能问题。
里卡多·桑切斯

21

我也无法更改文本颜色-我从未见过颜色变化。

直到我添加的代码的文本颜色更改为活动DataBindingsCompleteDataGridView。之后,它起作用了。

我希望这将帮助面临相同问题的人们。


在onLoad(..)覆盖或事件中,文本颜色不会更改。DataBindingsComplete是进行行颜色设置的好得多的地方。
蒂莫西

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

谢谢您的帮助。您的建议是我最接近解决问题的建议。但是我不断收到错误消息,说明上下文中不存在“值”或上下文中不存在“单元格”。试图弄清楚...
EB。

这行代码(dgvr.Cells [7]。价值<dgvr.Cells [10]。价值)现在给我此错误操作员“<”不能被施加到型“对象”和“对象”的操作数
EB。

然后将它们转换为整数。:-)类似:Convert.ToInt32(dvgr.Cells [7] .Value)<Convert.ToInt32(dgvr.Cells [10] .Value)
Demi 2010年

8

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


5

您可以Backcolor使用您的条件逐行更改。在应用DatasourceDatagridView

这是该功能。只需复制并放在后面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;                   
    //    }
    //}
}

2

这是我用bindingDataSource将颜色更改为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;
                }
            }

        }

    }
}

1

如果绑定到具体对象的(集合),则可以通过该行的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;
            }
        }

0

我通常喜欢为此使用GridView.RowDataBound事件事件。

protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.ForeColor = System.Drawing.Color.Red;
    }
}

1
在Window Application中要求他提供DatagridView。您的答案是关于Web的GridView。
Pratik 1020年

0

在Visual Studio 2010上可以使用。(我尝试过并且可以使用!) 它将绘制整个行。

  1. 为创建一个按钮datagridview
  2. 创建一个CellClick事件,并将下一行代码放入其中。

if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)    
{
    dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}

0

您没有提到价值如何变化。用户输入值时,我使用了类似的功能。即进入和离开编辑模式。

使用dataGriddview的CellEndEdit事件。

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

您可以添加逻辑以类似的方式清除错误通知。

如果您的情况是,如果以编程方式加载数据,则可以将CellLeave事件与相同的代码一起使用。


0

使用此代码,您只需要更改columname值为null的行的背景色,其他行的颜色仍然是默认值。

       foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells["columnname"].Value != null)
                    {
                        dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
                    }
                 }

0

只是关于设置的说明DefaultCellStyle.BackColor...您不能将其设置为任何透明值,除了Color.Empty。这是默认值。这错误地暗示了(无论如何对我而言)透明的颜色是可以的。他们不是。我设置为透明颜色的每一行仅绘制选定行的颜色。

在这个问题上,我花了太多时间在墙上碰头。


0

我降落在这里寻找不使用数据绑定的解决方案。什么都没有为我工作,但最终我得到了:

dataGridView.Columns.Clear(); 
dataGridView.Rows.Clear();
dataGridView.Refresh();

0

如果您是地球上第二大愚蠢的开发人员(我是最愚蠢的开发人员),那么上述所有解决方案似乎都可以使用:CellFormatting,DataSourceChanged和RowPrePaint。我更喜欢RowPrePaint。

我为此苦苦挣扎(时间太长了),因为在更改所选行时,需要覆盖我的SelectionBackColor和SelectionForeColor而不是BackColor和ForeColor。


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;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.