web-dev-qa-db-fra.com

Modification de la couleur de la cellule datagridview en fonction de la condition

J'ai chargé les données de la base de données dans datagridview et j'ai deux colonnes valeur cible et volume où volume> valeur cible cette cellule de volume doit être de couleur verte et volume <valeur cible, puis le volume doit être de couleur rouge. J'ai essayé mais je ne suis pas capable de le faire.

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

Tu dois faire ça 

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

En attendant, regardez aussi Formatage de cellule

18
Rohit

Je peux suggérer queNONne parcourt pas chaque ligne CHAQUE heure où CellFormating est appelé, car il est appelé à chaque fois qu'une seule ligne doit être rafraîchie.

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
18
Simon

Les réponses de Kyle et de Simon sont un gaspillage flagrant de ressources CPU. Les événements CellFormatting et CellPainting se produisent beaucoup trop de fois et ne doivent pas être utilisés pour appliquer des styles. Voici deux meilleures façons de le faire:

Si votre DataGridView ou au moins les colonnes qui décident du style de cellule sont en lecture seule, vous devez modifier DefaultCellStyle des lignes dans l'événement RowsAdded. Cet événement ne se produit qu'une fois lorsqu'une nouvelle ligne est ajoutée. La condition doit être évaluée à ce moment-là et DefaultCellStyle de la ligne doit y être défini. Notez que cet événement se produit également pour les situations DataBound.

Si votre DataGridView ou ces colonnes autorisent l’édition, vous devez utiliser les événements CellEndEdit ou CommitEdit pour modifier DefaultCellStyle.

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

Cela a parfaitement fonctionné pour moi. même si une ligne est modifiée, le même événement est pris en charge.

3
Sumit Agrawal

Sans bouclage, cela peut être réalisé comme ci-dessous.

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);
        }
    }
1
dilipkumar katre

Disons que vous devez colorer certaines cellules (pas toutes les cellules de la ligne) en sachant deux choses:

  1. Nom ou index de la colonne.
  2. Valeur qui va être à l'intérieur de la cellule.

Dans ce cas, vous devez utiliser event CellFormatting

Dans mon cas j'utilise comme ça

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

Et résultat vous pouvez voir ici 

 enter image description here

Vous pouvez donc accéder ici à certaines cellules de la ligne en colonne par son nom Row.Cells ["Decade1Hours"]

Comment connaissez-vous ce nom? Bien dans mon cas, je crée une colonne de DataGridView comme celle-ci.

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

Et bien ... vous devez par exemple coloriser certaines des cellules de la ligne, comme ## 1 4 5 et 8, vous devez utiliser un index de cellule (il commence à 0).

Et le code va lok comme 

 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;
    }
  }
}
1
private void dataGridView1_DataBindingComplete(object sender DataGridViewBindingCompleteEventArgs e)
{
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (Convert.ToInt32(row.Cells["balaceAmount"].Value) == 0)
        {
            row.DefaultCellStyle.BackColor = Color.Yellow;
        }
        else
        {
            row.DefaultCellStyle.BackColor = Color.White;
        }
    }
}
1
AJEET YA

Je sais que c'est un ancien post, mais j'ai trouvé mon chemin ici en 2018, alors peut-être que quelqu'un d'autre le fera aussi. À mon avis, le PO avait une meilleure approche (en utilisant l'événement dgv_DataBindingComplete) qu'aucune des réponses fournies. Au moment de la rédaction, toutes les réponses sont écrites à l'aide d'événements Paint ou d'événements de formatage de cellules, ce qui semble inefficace.

Le PO fonctionnait à 99%. Tout ce qu'ils avaient à faire, était de parcourir leurs lignes, de tester la valeur de cellule de chaque ligne et de définir le BackColor, le ForeColor ou toute autre propriété que vous souhaitez définir. 

S'il vous plaît excuser la syntaxe vb.NET, mais je pense que c'est assez proche de C # pour qu'il soit clair.

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
0
Scope Creep

Surpris, personne ne mentionne qu'une simple instruction if peut vous assurer que votre boucle n'est exécutée qu'une fois par format (sur la première colonne de la première ligne).

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