C# DataGridView 单行文本颜色

3

我有一个DataGridView,它的DataSource是一个类。

该类包含一个ID字符串、2个日期时间和一个布尔值。

我已经编写了一些代码,用于将匹配我传递给方法的ID的行的文本更改为红色,但是我尝试过的所有方法都没有起作用。

到目前为止,我的代码如下:

public void ShowInstanceAsTerminated(String id)
{
    foreach (DataGridViewRow dgvRow in dgvRIM.Rows)
    {
        if (dgvRow.Cells[0].Value.ToString() == id)
        {
            dgvRow.DefaultCellStyle.ForeColor = Color.Red;
        }
    }
}

这是我尝试过的许多代码变体之一,但是相关单元格从未发生变化!!

谢谢 Neil

8个回答

13

尝试使用这种格式:

dgvRIM.Rows[myRow].Cells[0].Style.ForeColor = Color.Red;

如果你想设置整个行,那么需要循环遍历所有单元格。


好的回答。有没有比逐个处理所有单元格更高效的方法?如果数据表格中有许多行,我会预期在刷新时性能会下降。有什么想法吗? - chonerman
1
@chonerman:我不认为仅仅设置属性会非常昂贵。在物理上不可见的行在实际变得可见之前不应该产生重新渲染的成本。在尝试优化问题之前,我会测试你对“许多行”的定义的性能。 - Eric J.
@EricJ. 感谢您的建议。我现在正在使用一个生产票务系统,大约有3k行并且还在增长。我找到了一种设置整个行而不是每个单元格的方法,并且它确实有助于提高性能。随着票数随着时间的推移增加,我将不得不限制我的返回查询,以便呈现不会拖慢用户。(例如:ticket_dgv1.Rows[d].DefaultCellStyle.BackColor = Color.Pink;) - chonerman
@chonerman:我同意你应该限制结果集,不是因为性能问题,而是因为3000多行在用户界面中对最终用户来说可能没有用处。这只是太长了需要滚动查看。 - Eric J.
@EricJ. 同意。但这是我正在处理的后端 GUI。前端是一个网页应用程序,具有分页和限制功能。 - chonerman
显示剩余7条评论

6
使用 DataGridView 的 CellFormatting 事件来修改组成行的单元格。类似以下内容(注意,未经测试):
private void dgvRIM_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
  if (dgvRIM.Rows[e.RowIndex].Cells[0].Value.ToString() == id) {
    e.CellStyle.ForeColor = Color.Red;
  }
}

+1. Vivek,他不能使用e.Value,他想要检查行的第一个单元格的值,这不一定是当前单元格的值。 - Meta-Knight
这个方法可行,可以设置整行单元格的样式,而无需循环遍历每个单元格。 - armadillo.mx

1
row.DefaultCellStyle.ForeColor = Color.Red;

这适用于至少 .NET 4.0 及以上版本。保留 HTML,不作解释。

1
这将正常工作。
private void grid1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
  DataGridViewRow row = grid1.Rows[e.RowIndex];// get you required index
  // check the cell value under your specific column and then you can toggle your colors
  row.DefaultCellStyle.BackColor = Color.Green;
}

0
我相信解决方案在于你设置颜色的时间,而不是你使用的方法。已经提出了几种不同的事件,有些确实有效。使用单元格格式、数据绑定完成甚至绘制事件的问题之一是它们会被多次触发。据我所知,datagridview控件存在一个问题,即在显示窗体之后才能更改任何单元格的颜色。因此,在调用Shown()之前运行或触发的事件将不会更改颜色。通常被认为是解决问题的事件通常有效,但由于它们被多次调用,可能不是最有效的答案。
解决这个问题最简单的方法可能是将填充/着色网格的代码放在窗体的Shown()方法中,而不是构造函数中。下面是一个链接,指向msdn论坛上的一个帖子,提示了我解决方案,该帖子在页面的3/4处标记为答案。 MSDN论坛帖子,其中包含解决方案

0

看起来 TabControl 存在一个 bug,即当它有多个选项卡时,使用代码创建的 cellstyles 只会应用于第一个选项卡的 DataGridView,因此为了解决这个问题,您可以将您的 DataGridView 移动到第一个选项卡,或者您可以使用 TabControl 的 SelectedIndexChanged 事件,并将您的样式代码放在此事件中。


0

您需要更改单个单元格。

这是从一个应用程序中提取的VB代码,我能够成功地完成此操作,但将其转换为C#不应该太难。

For i As Integer = 0 To ds.Tables("AddressChanges").Rows.Count - 1
                If ds.Tables("AddressChanges").Rows(i)("iSeriesAddress").ToString <> ds.Tables("AddressChanges").Rows(i)("CSIAddress").ToString() Then
                    Me.dgAddressDiscrepancies.Rows(i).Cells("iSeriesAddress").Style.BackColor = Color.Yellow
                    Me.dgAddressDiscrepancies.Rows(i).Cells("CSIAddress").Style.BackColor = Color.Yellow
                End If
Next

他想要更改行的前景色,这可以在不必修改每个单元格的前景色/背景色的情况下完成。 - Hasani Blackwell
理论上你应该是对的,但在实践中,我发现它不起作用。除非有什么改变了。我的代码是.Net 2.0,所以DataGridView可能已经更新了,但正如他在问题中所说,如果你尝试将其应用到一行,它不会抛出错误,但也不会改变颜色。无论如何,我的答案是改变背景颜色,而不是前景颜色,但概念是相同的。@Eric J用更好、更清晰的形式回答了同样的想法。 - David
@David Stratton:我刚刚测试了一下,它确实可以工作(请参见我的答案)。为什么在你的情况下它不起作用?为什么为单个单元格设置ForeColor会更好? - Meta-Knight

0

我刚刚测试了你的代码(使用DefaultCellStyle设置ForeColor),它确实有效(在.NET 3.5上,但我认为自2.0以来Winforms并没有发展)。

现在我不知道为什么它对你不起作用...也许你在添加行之前调用了代码,或者在调用代码后重新加载了行?

无论如何,你可能最好采用Jay Riggs的解决方案,因为即使在添加新行之后,它也能正常工作。


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