C# 根据条件更改 datagridview 单元格颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19380279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:50:48  来源:igfitidea点击:

Changing datagridview cell color based on condition

c#winformsdatagridview

提问by preethi

I have loaded the data from database to datagridview and have two columns target value and volume where volume >target value that volume cell should be in green color and volume < target value then volume should be in red color. I tried it but I am not able to do it.

我已将数据从数据库加载到 datagridview 并有两列目标值和体积,其中体积 > 目标值,体积单元格应为绿色,体积 < 目标值,然后体积应为红色。我试过了,但我做不到。

private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    if (dataGridView1.Rows.Count > 0 && dataGridView1.Columns.Count > 0)
    {
        foreach (DataGridViewRow r in dataGridView1.Rows)
        {
            if (Volume > target value)
            {
                cell.Style.BackColor = Color.AliceBlue;
            } 

采纳答案by Rohit

You need to do this

你需要这样做

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    foreach (DataGridViewRow Myrow in dataGridView1.Rows) 
    {            //Here 2 cell is target value and 1 cell is Volume
        if (Convert.ToInt32(Myrow .Cells[2].Value)<Convert.ToInt32(Myrow .Cells[1].Value))// Or your condition 
        {
            Myrow .DefaultCellStyle.BackColor = Color.Red; 
        }
        else
        {
            Myrow .DefaultCellStyle.BackColor = Color.Green; 
        }
    }
}

Meanwhile also take a look at Cell Formatting

同时也看看单元格格式

回答by Simon

I may suggest NOTlooping over each rows EACH time CellFormating is called, because it is called everytime A SINGLE ROW need to be refreshed.

我可能建议不要在每次调用 CellFormating 时循环遍历每一行,因为每次需要刷新 A SINGLE ROW 时都会调用它。

Private Sub dgv_DisplayData_Vertical_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles dgv_DisplayData_Vertical.CellFormatting
        Try

            If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "6" Then

                e.CellStyle.BackColor = Color.DimGray
            End If
            If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "5" Then
                e.CellStyle.BackColor = Color.DarkSlateGray
            End If
            If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "4" Then
                e.CellStyle.BackColor = Color.SlateGray
            End If
            If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "3" Then
                e.CellStyle.BackColor = Color.LightGray
            End If
            If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "0" Then
                e.CellStyle.BackColor = Color.White
            End If

        Catch ex As Exception

        End Try

    End Sub

回答by dotNET

Kyle's and Simon's answers are gross waste of CPU resources. CellFormattingand CellPaintingevents occur far too many times and should not be used for applying styles. Here are two better ways of doing it:

Kyle 和 Simon 的回答是对 CPU 资源的严重浪费。CellFormattingCellPainting事件发生的次数太多,不应用于应用样式。这里有两种更好的方法:

If your DataGridView or at least the columns that decide cell style are read-only, you should change DefaultCellStyle of rows in RowsAddedevent. This event occurs only once when a new row is added. The condition should be evaluated at that time and DefaultCellStyleof the row should be set therein. Note that this event occurs for DataBound situations too.

如果您的 DataGridView 或至少决定单元格样式的列是只读的,您应该在RowsAdded事件中更改行的 DefaultCellStyle 。此事件仅在添加新行时发​​生一次。应在那时评估条件并DefaultCellStyle在其中设置行。请注意,此事件也会在 DataBound 情况下发生。

If your DataGridView or those columns allow editing, you should use CellEndEditor CommitEditevents to change DefaultCellStyle.

如果您的 DataGridView 或那些列允许编辑,您应该使用CellEndEditCommitEdit事件来更改DefaultCellStyle.

回答by Sumit Agrawal

foreach (DataGridViewRow row in dgvWebData.Rows)
{
    if (Convert.ToString(row.Cells["IssuerName"].Value) != Convert.ToString(row.Cells["SearchTermUsed"].Value))
    {
        row.DefaultCellStyle.BackColor = Color.Yellow;
    }
    else
    {
        row.DefaultCellStyle.BackColor = Color.White;
    }
}

This Perfectly worked for me . even if a row is changed, same event takes care.

这对我来说非常有用。即使更改了一行,也会处理相同的事件。

回答by Muhammad ElBarawi

//After Done Binding DataGridView Data
foreach(DataGridViewRow DGVR in DGV_DETAILED_DEF.Rows)
{
    if(DGVR.Index != -1)
    {
        if(DGVR.Cells[0].Value.ToString() == "???????")
        {
            CurrRType = "???????";
            DataGridViewCellStyle CS = DGVR.DefaultCellStyle;
            CS.BackColor = Color.FromArgb(0,175,100);
            CS.ForeColor = Color.FromArgb(0,32,15);

            CS.Font = new Font("Times New Roman",12,FontStyle.Bold);
            CS.SelectionBackColor = Color.FromArgb(0,175,100);
            CS.SelectionForeColor = Color.FromArgb(0,32,15);
            DataGridViewCellStyle LCS = DGVR.Cells[DGVR.Cells.Count - 1].Style;
            LCS.BackColor = Color.FromArgb(50,50,50);
            LCS.SelectionBackColor = Color.FromArgb(50,50,50);
        }
        else if(DGVR.Cells[0].Value.ToString() == "???????????")
        {
            CurrRType = "???????????";
            DataGridViewCellStyle CS = DGVR.DefaultCellStyle;
            CS.BackColor = Color.FromArgb(175,0,50);
            CS.ForeColor = Color.FromArgb(32,0,0);
            CS.Font = new Font("Times New Roman",12,FontStyle.Bold);
            CS.SelectionBackColor = Color.FromArgb(175,0,50);
            CS.SelectionForeColor = Color.FromArgb(32,0,0);
            DataGridViewCellStyle LCS = DGVR.Cells[DGVR.Cells.Count - 1].Style;
            LCS.BackColor = Color.FromArgb(50,50,50);
            LCS.SelectionBackColor = Color.FromArgb(50,50,50);
        }
    }
}

回答by Ramgy Borja

make it simple

让它变得简单

private void dataGridView1_cellformatting(object sender,DataGridViewCellFormattingEventArgs e)
{
     var amount = (int)e.Value;

     // return if rowCount = 0
     if (this.dataGridView1.Rows.Count == 0)
         return;

     if (amount > 0)
         e.CellStyle.BackColor = Color.Green; 
     else
         e.CellStyle.BackColor = Color.Red;

}

take a look cell formatting

看看单元格格式

回答by Developer

Let's say you have to color certain cell (not all cells of the row) by knowing two things:

假设您必须通过了解两件事来为某些单元格(不是该行的所有单元格)着色:

  1. Name or index of the column.
  2. Value which is gonna be inside of the cell.
  1. 列的名称或索引。
  2. 值将在单元格内。

In thas case you have to use event CellFormatting

在这种情况下,您必须使用事件CellFormatting

In my case I use like this

在我的情况下,我像这样使用

private void DgvTrucksMaster_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
     foreach (DataGridViewRow row in dgvTrucksMaster.Rows)
     {
       if (Convert.ToInt32(row.Cells["Decade1Hours"].Value) > 0)
       {
          row.Cells["Decade1Hours"].Style.BackColor = Color.LightGreen;
       }
       else if (Convert.ToInt32(row.Cells["Decade1Hours"].Value) < 0)
       {
          // row.DefaultCellStyle.BackColor = Color.LightSalmon; // Use it in order to colorize all cells of the row

          row.Cells["Decade1Hours"].Style.BackColor = Color.LightSalmon;
       }
     }
}

And result you can see here

结果你可以在这里看到

enter image description here

在此处输入图片说明

So here you can access certain cell of the row in column by its name row.Cells["Decade1Hours"]

因此,在这里您可以通过名称 row.Cells["Decade1Hours"] 访问列中行的某些单元格

How do you know this name? Well in my case i create column of DataGridView like this.

你怎么知道这个名字的?那么在我的情况下,我像这样创建 DataGridView 列。

var Decade1Hours = new DataGridViewTextBoxColumn()
{
   Name = "Decade1Hours",
   Width = 50,
   DataPropertyName = "Decade1Hours",
   ReadOnly = true,
   DefaultCellStyle = new DataGridViewCellStyle()
       {
        Alignment = DataGridViewContentAlignment.MiddleCenter,
        ForeColor = System.Drawing.Color.Black,
        Font = new Font(font, FontStyle.Bold),
        Format = "n2"
      },
   HeaderCell = new DataGridViewColumnHeaderCell()
      {
          Style = new DataGridViewCellStyle()
               {
                 Alignment = DataGridViewContentAlignment.MiddleCenter,
                 BackColor = System.Drawing.Color.Blue
               }
       }
};
Decade1Hours.HeaderText = "Дек.1";
dgvTrucksMaster.Columns.Add(Decade1Hours);

And well... you you need for instance colorize some of the cells in the row like ##1 4 5 and 8 you have to use cell index (it starts from 0).

嗯……你需要例如为行中的一些单元格着色,比如 ##1 4 5 和 8 你必须使用单元格索引(它从 0 开始)。

And code will lok like

代码看起来像

 private void DgvTrucksMaster_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
  foreach (DataGridViewRow row in dgvTrucksMaster.Rows)
  {
    if (Convert.ToInt32(row.Cells[1].Value) > 0 )
    {
      row.Cells[1].Style.BackColor = Color.LightGreen;
    }
  }
}

回答by clamchoda

Surprised no one mentioned a simple ifstatement can make sure your loop only gets executed once per format (on the first column, of the first row).

令人惊讶的是,没有人提到一个简单的if语句可以确保您的循环只在每种格式中执行一次(在第一行的第一列上)。

    private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        // once per format
        if (e.ColumnIndex == 0 && e.RowIndex == 0)
        {
            foreach (DataGridViewRow row in dgv.Rows)
                if (row != null)
                    row.DefaultCellStyle.BackColor = Color.Red;
        }
    }

回答by dilipkumar katre

Without looping it can be achived like below.

没有循环它可以像下面那样实现。

private void dgEvents_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
    {

        FormatRow(dgEvents.Rows[e.RowIndex]);

    }

private void FormatRow(DataGridViewRow myrow)
    {
        try
        {
            if (Convert.ToString(myrow.Cells["LevelDisplayName"].Value) == "Error")
            {
                myrow.DefaultCellStyle.BackColor = Color.Red;
            }
            else if (Convert.ToString(myrow.Cells["LevelDisplayName"].Value) == "Warning")
            {
                myrow.DefaultCellStyle.BackColor = Color.Yellow;
            }
            else if (Convert.ToString(myrow.Cells["LevelDisplayName"].Value) == "Information")
            {
                myrow.DefaultCellStyle.BackColor = Color.LightGreen;
            }
        }
        catch (Exception exception)
        {
            onLogs?.Invoke(exception.Message, EventArgs.Empty);
        }
    }

回答by Scope Creep

I know this is an old post, but I found my way here in 2018, so maybe someone else will too. In my opinion, the OP had a better approach (using dgv_DataBindingComplete event) than any of the answers provided. At the time of writing, all of the answers are written using paint events or cellformatting events which seems inefficient.

我知道这是一个旧帖子,但我在 2018 年找到了我的方式,所以也许其他人也会这样做。在我看来,OP 有比提供的任何答案更好的方法(使用 dgv_DataBindingComplete 事件)。在撰写本文时,所有答案都是使用绘制事件或单元格格式事件编写的,这似乎效率低下。

The OP was 99% of the way there, all they had to do was loop through their rows, test the cell value of each row, and set the BackColor, ForeColor, or whatever other property you want to set.

OP 完成了 99% 的工作,他们所要做的就是遍历他们的行,测试每一行的单元格值,并设置 BackColor、ForeColor 或您想要设置的任何其他属性。

Please excuse the vb.NET syntax, but I think its close enough to C# that it should be clear.

请原谅 vb.NET 语法,但我认为它与 C# 足够接近,应该很清楚。

Private Sub dgvFinancialResults_DataBindingComplete Handles dgvFinancialResults.DataBindingComplete
            Try
                Logging.TraceIt()
                For Each row As DataGridViewRow in dgvFinancialResults.Rows
                    Dim invoicePricePercentChange = CSng(row.Cells("Invoice Price % Change").Value)
                    Dim netPricePercentChange = CSng(row.Cells("Net Price % Change").Value)
                    Dim tradespendPricePercentChange = CSng(row.Cells("Trade Spend % Change").Value)
                    Dim dnnsiPercentChange = CSng(row.Cells("DNNSI % Change").Value)
                    Dim cogsPercentChange = CSng(row.Cells("COGS % Change").Value)
                    Dim grossProfitPercentChange = CSng(row.Cells("Gross Profit % Change").Value)


                    If invoicePricePercentChange > Single.Epsilon Then
                        row.Cells("Invoice Price % Change").Style.ForeColor = Color.Green
                    Else
                        row.Cells("Invoice Price % Change").Style.ForeColor = Color.Red
                    End If

                    If netPricePercentChange > Single.Epsilon Then
                        row.Cells("Net Price % Change").Style.ForeColor = Color.Green
                    Else
                        row.Cells("Net Price % Change").Style.ForeColor = Color.Red
                    End If

                    If tradespendPricePercentChange > Single.Epsilon Then
                        row.Cells("Trade Spend % Change").Style.ForeColor = Color.Green
                    Else
                        row.Cells("Trade Spend % Change").Style.ForeColor = Color.Red
                    End If

                    If dnnsiPercentChange > Single.Epsilon Then
                        row.Cells("DNNSI % Change").Style.ForeColor = Color.Green
                    Else
                        row.Cells("DNNSI % Change").Style.ForeColor = Color.Red
                    End If

                    If cogsPercentChange > Single.Epsilon Then
                        row.Cells("COGS % Change").Style.ForeColor = Color.Green
                    Else
                        row.Cells("COGS % Change").Style.ForeColor = Color.Red
                    End If

                    If grossProfitPercentChange > Single.Epsilon Then
                        row.Cells("Gross Profit % Change").Style.ForeColor = Color.Green
                    Else
                        row.Cells("Gross Profit % Change").Style.ForeColor = Color.Red
                    End If
                Next
            Catch ex As Exception
                Logging.ErrorHandler(ex)
            End Try
        End Sub