C#迭代DataGridView并更改行颜色

23
我有一个由多行和列组成的数据表格。 我想遍历每一行并检查特定列的内容。 如果该列包含单词“NO”,则将整行的前景色更改为红色。 这是目前为止的一些代码尝试,但肯定不起作用,开始怀疑是否需要遍历每个单元格?
CODE:
foreach (DataGridViewRow dgvr in dataGridView1.Rows)
        {
            if (dgvr.Cells["FollowedUp"].Value.ToString() == ("No"))
            {
                dgvr.DefaultCellStyle.ForeColor = Color.Red;
            }
        }

1
“不起作用”指的是什么?没有行吗?找不到单元格? - Colin
7个回答

26

挂接 OnRowDataBound 事件,然后做相应处理。

ASPX (表格):

    <asp:.... OnRowDataBound="RowDataBound"..../>

后台代码:

    protected void RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowIndex == -1)
        {
            return;
        }

        if(e.Row.Cells[YOUR_COLUMN_INDEX].Text=="NO"){
             e.Row.BackColor=Color.Red;   
        }
    }

对于 WinForms:

hook the **DataBindingComplete** event and do stuff in it:

     private void dataGridView1_DataBindingComplete(object sender, 
                       DataGridViewBindingCompleteEventArgs e)
    {
        if (e.ListChangedType != ListChangedType.ItemDeleted)
        {
            DataGridViewCellStyle red = dataGridView1.DefaultCellStyle.Clone();
            red.BackColor=Color.Red;

            foreach (DataGridViewRow r in dataGridView1.Rows)
            {
                if (r.Cells["FollowedUp"].Value.ToString()
                       .ToUpper().Contains("NO"))
                {
                    r.DefaultCellStyle = red;
                }
            }
        }
    }

1
糟糕!所有的东西都是关于Web的,而我自己深陷于Web项目中已经有3个月了,以至于每个问题都似乎与ASP.NET有关。 - TheVillageIdiot
不是我,但我猜可能是因为它与问题无关?(即问题标记为Winforms):-/ - BrainSlugs83

9
在您的DataGridView上,处理CellFormatting事件:
dataGridView1.CellFormatting += new DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting);

您的事件处理程序可能如下所示:

您的事件处理程序可能如下所示:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{       
    if(dataGridView1.Columns[e.ColumnIndex].Name == "FollowedUp" && e.Value != null && e.Value.ToString() == "No")
        dataGridView1.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Red;  
}

这样,您不会“迭代”行 - 仅在网格中可见时(因此需要格式化),更改它们绘制/绘制的颜色。


这种方法慢得多,但是格式不会因为列标题单击排序而被删除。 - B H
抱歉,我的事件处理程序代码替换出了一些问题,我无法编辑之前的评论。我会将“a LOT”替换为“稍微”慢一些。 - B H
根据您在处理程序中所做的操作,将决定大部分性能。但最终,使用处理程序方法意味着(正如您所说)它不会被列排序擦除。此外,在具有数千行的网格的情况下,您也不需要“格式化”用户可能永远看不到的行。 - Rostov

6
public void ColourChange()
    {
        DataGridViewCellStyle RedCellStyle = null;
        RedCellStyle = new DataGridViewCellStyle();
        RedCellStyle.ForeColor = Color.Red;
        DataGridViewCellStyle GreenCellStyle = null;
        GreenCellStyle = new DataGridViewCellStyle();
        GreenCellStyle.ForeColor = Color.Green;


        foreach (DataGridViewRow dgvr in dataGridView1.Rows)
        {
            if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No"))
            {
                dgvr.DefaultCellStyle = RedCellStyle;
            }
            if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("Yes"))
            {
                dgvr.DefaultCellStyle = GreenCellStyle;
            }
        }
    }

10
将[Type x = null; x = new Type();]合并成[Type x = new Type();]并没有影响你的收益。 - Mark Rushakoff

2

单元格的值中是否可能包含空格或其他字符?如果是,请尝试使用包含(Contains)方法而不是直接使用相等性判断。

if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No"))

0

这是Winforms的解决方案:

private void HighlightRows()
{
    DataGridViewCellStyle GreenStyle = null;

    if (this.dgridv.DataSource != null)
    {
        RedCellStyle = new DataGridViewCellStyle();
        RedCellStyle.BackColor = Color.Red;

        for (Int32 i = 0; i < this.dgridv.Rows.Count; i++)
        {
            if (((DataTable)this.dgridv.DataSource).Rows[i]["col_name"].ToString().ToUpper() == "NO")
            {
                this.dgridv.Rows[i].DefaultCellStyle = RedCellStyle;
                continue;
            }
        }
    }
}

没有异常和颜色改变。我不知道为什么,请帮忙。 - Muhammad Mubashir

0
private void Grd_Cust_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    colorCode == 4 ? Color.Yellow : Color.Brown;
    if (e.RowIndex < 0 || Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value == DBNull.Value)
        return;
    string colorCode = Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value.ToString();
    e.CellStyle.BackColor = colorCode == "NO" ? Color.Red : Grd_Cust.DefaultCellStyle.BackColor;
}

1
欢迎来到stackoverflow。提示:您可以使用“{}”按钮来格式化您的代码片段。 - Leigh

0

这段代码对我来说很好用:


foreach (DataGridViewRow row in dataGridView1.Rows)
{
    if ((string)row.Cells["property_name"].Value == UNKNOWN_PROPERTY_NAME)
    {
        row.DefaultCellStyle.BackColor = Color.LightSalmon;
        row.DefaultCellStyle.SelectionBackColor = Color.Salmon;
    }
}

除了将其转换为字符串而不是调用ToString之外,我真的看不出有什么区别,所以可能是大小写敏感的错误。尝试使用:

dgvr.Cells["FollowedUp"].Value.ToString().ToUpper() == "NO"

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