Risposte:
È 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;
}
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 RowPrePaint
dell'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;
}
}
Stai cercando l' CellFormatting
evento.
Ecco un esempio
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 DataBindingsComplete
perDataGridView
. Dopodiché ha funzionato.
Spero che questo possa aiutare le persone che affrontano lo stesso problema.
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;
}
Ad alcune persone piace usare i Paint
, CellPainting
o CellFormatting
eventi, ma è da notare che cambiare uno stile in questi eventi provoca chiamate ricorsive. Se lo usi DataBindingComplete
verrà 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.
Puoi cambiare Backcolor
riga per riga usando la tua condizione e questa chiamata di funzione dopo l'applicazione Datasource
di 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;
}
}
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;
// }
//}
}
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;
}
}
}
}
}
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;
}
}
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;
}
}
Funziona su Visual Studio 2010. (L'ho provato e funziona!) Dipingerà l'intera riga.
datagridview
.CellClick
evento 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;
}
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.
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;
}
}
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.
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();
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.
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;
}
}