Come cambiare il colore delle righe in Datagridview?


143

Vorrei cambiare il colore di una riga particolare nella mia vista dati. La riga deve essere modificata in rosso quando il valore di columncell 7 è inferiore al valore in columncell 10. Qualche suggerimento su come ottenere questo risultato?

Risposte:


192

È necessario scorrere le righe nella vista dati e quindi confrontare i valori delle colonne 7 e 10 su ciascuna riga.

Prova questo:

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
Grazie per l'aiuto Ricardo. Ho provato il codice che mi hai suggerito. Non riesco ancora a farlo funzionare. Ti dispiacerebbe dare un'occhiata a questo codice e dirmi dove ho sbagliato? Sono uno studente C # principiante. Sono sicuro di non aver scritto correttamente il codice di confronto. foreach (DataGridView row in vendorsDataGridView.Rows) {if (row.Cells [7] .Value is <row.Cells [10] .Value) {dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } Apprezzo il vostro aiuto. EB
EB.

EB Ho aggiunto un nuovo codice basato sul codice che hai fornito. La tua sintassi era un po 'spenta, prova il codice che ho appena aggiunto sopra.
Ricardo Sanchez,

2
Ricardo. Ho cambiato .text in .value e modificato in DefaultCellstyle.Backcolor = color.red e il codice ha funzionato !!! Grazie per il tuo tempo! EB
EB.

60

Stavo solo studiando questo problema (quindi so che questa domanda è stata pubblicata quasi 3 anni fa, ma forse aiuterà qualcuno ...) ma sembra che un'opzione migliore sia inserire il codice all'interno RowPrePaintdell'evento in modo da non farlo deve attraversare ogni riga, solo quelle che vengono dipinte (quindi funzionerà molto meglio su una grande quantità di dati:

Allega all'evento

this.dataGridView1.RowPrePaint 
    += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
        this.dataGridView1_RowPrePaint);

Il codice evento

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
Mi piace molto come affronti il ​​problema alla radice invece di aspettare fino a quando tutto è stato dipinto. Questo è un approccio molto "fuori dagli schemi". La maggior parte delle persone preferisce semplicemente ripetere ogni fila ...
bird2920

Oltre ad essere molto più veloce, aiuta anche a farlo al momento giusto. Ho avuto problemi con le mie righe che non venivano colorate, probabilmente perché avevo impostato il colore nel momento sbagliato. Con questo approccio, è garantito che avvenga al momento giusto.
sanderd17,

1
Funziona bene. Anche dopo aver ordinato il suo aggiornamento in modo corretto.
macmuri,

24

Stai cercando l' CellFormattingevento.
Ecco un esempio


2
La differenza con questo approccio è che ogni singola cella verrà confrontata rispetto a una sola. Potrebbe essere un problema di prestazioni se hai diverse centinaia di celle.
Ricardo Sanchez,

21

Ho avuto problemi anche a cambiare il colore del testo - non ho mai visto il cambiamento di colore.

Fino a quando non ho aggiunto il codice per cambiare il colore del testo all'evento DataBindingsCompleteperDataGridView . Dopodiché ha funzionato.

Spero che questo possa aiutare le persone che affrontano lo stesso problema.


il colore del testo non cambia quando è attivo overLide (..) o l'evento. DataBindingsComplete è il posto migliore per eseguire l'impostazione del colore delle righe.
timothy

13

Qualcosa di simile al seguente ... supponendo che i valori nelle celle siano numeri interi.

foreach (DataGridViewRow dgvr in myDGV.Rows)
{
  if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
  {
    dgvr.DefaultCellStyle.ForeColor = Color.Red;
  }
}

non testato, quindi mi scuso per qualsiasi errore.

Se conosci la riga specifica, puoi saltare l'iterazione:

if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
  dgvr.DefaultCellStyle.ForeColor = Color.Red;
}

Grazie per l'aiuto. Il tuo suggerimento è il più vicino che ho avuto per risolvere il problema. Ma continuo a ricevere l'errore che dice che "Valore" non esiste nel contesto o "Celle" non esiste nel contesto. Sto cercando di capirlo ...
EB.

questa riga di codice (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) ora mi dà questo errore L'operatore '<' non può essere applicato agli operandi di tipo 'oggetto' e 'oggetto'
EB.

Trasmetterli a Integer, quindi. :-) qualcosa del tipo: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Demi

8

Ad alcune persone piace usare i Paint, CellPaintingo CellFormattingeventi, ma è da notare che cambiare uno stile in questi eventi provoca chiamate ricorsive. Se lo usi DataBindingCompleteverrà eseguito solo una volta. L'argomento CellFormattingè che viene chiamato solo su celle visibili, quindi non è necessario formattare celle non visibili, ma formattarle più volte.


5

Puoi cambiare Backcolorriga per riga usando la tua condizione e questa chiamata di funzione dopo l'applicazione Datasourcedi DatagridView.

Ecco la funzione per questo. Basta copiarlo e inserirlo dopoDatabind

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

Questa è la mia soluzione per cambiare il colore in dataGridView con bindingDataSource:

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

Se si esegue il binding a una (raccolta) di oggetti concreti, è possibile ottenere l'oggetto concreto tramite la proprietà DataBoundItem della riga. (Per evitare il controllo delle stringhe magiche nella cella e l'utilizzo delle proprietà "reali" dell'oggetto)

Esempio di scheletro di seguito:

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

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

quindi il gestore eventi e ottenere l'oggetto concreto (anziché un DataGridRow e / o celle)

        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

In genere mi piace utilizzare l'evento GridView.RowDataBound per questo.

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

1
Gli viene chiesto DatagridView nell'applicazione Window. E la tua risposta riguarda GridView del Web.
Pratik 1020,

0

Funziona su Visual Studio 2010. (L'ho provato e funziona!) Dipingerà l'intera riga.

  1. Crea un pulsante per il datagridview .
  2. Crea un CellClickevento e inserisci la riga di codice successiva al suo interno.

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

0

Non hai menzionato come viene modificato il valore. Ho usato funzionalità simili quando l'utente sta inserendo un valore. cioè entrare e uscire dalla modalità modifica.

Utilizzo dell'evento CellEndEdit di datagridview.

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

È possibile aggiungere la logica per cancellare la notifica degli errori in modo simile.

se nel tuo caso, se i dati vengono caricati a livello di codice , è possibile utilizzare l'evento CellLeave con lo stesso codice.


0

Con questo codice, cambi solo le righe backcolor dove il valore del nome colonna è null altre righe colorano ancora quella predefinita.

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

0

Solo una nota sull'impostazione DefaultCellStyle.BackColor... non puoi impostarlo su nessun valore trasparente tranneColor.Empty . Questo è il valore predefinito. Ciò implica erroneamente (per me, comunque) che i colori trasparenti sono OK. Loro non sono. Ogni riga impostata su un colore trasparente disegna semplicemente il colore delle righe selezionate.

Ho passato troppo tempo a battere la testa contro il muro per questo problema.


0

Sono atterrato qui alla ricerca di una soluzione per il caso in cui non utilizzo l'associazione dati. Niente ha funzionato per me, ma alla fine ho capito:

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

0

Se sei il secondo sviluppatore più stupido del pianeta (io sono il più stupido), tutte le soluzioni di cui sopra sembrano funzionare: CellFormatting, DataSourceChanged e RowPrePaint. Preferisco RowPrePaint.

Ho lottato con questo (per troppo tempo) perché avevo bisogno di sovrascrivere SelectionBackColor e SelectionForeColor anziché BackColor e ForeColor mentre stavo cambiando la riga selezionata.


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;
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.