Respuestas:
Debe recorrer las filas en la vista de cuadrícula de datos y luego comparar los valores de las columnas 7 y 10 en cada fila.
Prueba esto:
foreach (DataGridViewRow row in vendorsDataGridView.Rows)
if (Convert.ToInt32(row.Cells[7].Value) < Convert.ToInt32(row.Cells[10].Value))
{
row.DefaultCellStyle.BackColor = Color.Red;
}
Estaba investigando este problema (así que sé que esta pregunta se publicó hace casi 3 años, pero tal vez ayude a alguien ...) pero parece que una mejor opción es colocar el código dentro del RowPrePaint
evento para que no tiene que atravesar cada fila, solo las que se pintan (por lo que funcionará mucho mejor en gran cantidad de datos:
Adjuntar al evento
this.dataGridView1.RowPrePaint
+= new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
this.dataGridView1_RowPrePaint);
El código del 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;
}
}
Estás buscando el CellFormatting
evento.
Aquí hay un ejemplo.
También tuve problemas para cambiar el color del texto: nunca vi cambiar el color.
Hasta he añadido el código para cambiar el color del texto al evento DataBindingsComplete
para DataGridView
. Después de eso funcionó.
Espero que esto ayude a las personas que enfrentan el mismo problema.
Algo como lo siguiente ... suponiendo que los valores en las celdas son enteros.
foreach (DataGridViewRow dgvr in myDGV.Rows)
{
if (dgvr.Cells[7].Value < dgvr.Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
}
no probado, así que disculpas por cualquier error.
Si conoce la fila en particular, puede omitir la iteración:
if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
Algunas personas les gusta usar las Paint
, CellPainting
o CellFormatting
eventos, pero tenga en cuenta que el cambio de un estilo en estos eventos hace que las llamadas recursivas. Si lo usa DataBindingComplete
, se ejecutará solo una vez. El argumento a favor CellFormatting
es que solo se llama en celdas visibles, por lo que no tiene que formatear celdas no visibles, sino que las formatea varias veces.
Puede cambiar Backcolor
fila por fila utilizando su condition.and esta llamada de función después de la aplicación Datasource
de DatagridView
.
Aquí está la función para eso. Simplemente copie eso y póngalo despuésDatabind
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;
// }
//}
}
Esta es mi solución para cambiar el color a 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;
}
}
}
}
}
Si se une a una (colección) de objetos concretos, puede obtener ese objeto concreto a través de la propiedad DataBoundItem de la fila. (Para evitar la búsqueda de cadenas mágicas en la celda y el uso de propiedades "reales" del objeto)
Ejemplo de esqueleto a continuación:
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;}
}
Enlace a la vista de cuadrícula de datos
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;
}
luego el controlador de eventos y obtener el objeto concreto (en lugar de un DataGridRow y / o celdas)
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;
}
}
Por lo general, me gusta usar el evento GridView.RowDataBound Event para esto.
protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.ForeColor = System.Drawing.Color.Red;
}
}
Funciona en Visual Studio 2010. (¡Lo probé y funciona!) Pintará toda tu fila.
datagridview
.CellClick
evento y coloque la siguiente línea de código dentro de él.if (dataGridView3.Columns[e.ColumnIndex].Index.Equals(0)
{
dataGridView3.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
No ha mencionado cómo se cambia el valor. He utilizado una funcionalidad similar cuando el usuario ingresa el valor. es decir, entrar y salir del modo de edición.
Usando el evento CellEndEdit de 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";
}
}
}
Puede agregar lógica para borrar la notificación de errores de manera similar.
si en su caso, si los datos se cargan mediante programación, el evento CellLeave se puede usar con el mismo código.
Con este código, solo cambia el color de fondo de las filas donde el valor del nombre de columna es nulo, el color de otras filas sigue siendo el predeterminado.
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["columnname"].Value != null)
{
dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.MistyRose;
}
}
Solo una nota sobre la configuración DefaultCellStyle.BackColor
... no puede establecerlo en ningún valor transparente excepto Color.Empty
. Ese es el valor predeterminado. Eso implica falsamente (para mí, de todos modos) que los colores transparentes están bien. Ellos no están. Cada fila que configuro en un color transparente solo dibuja el color de las filas seleccionadas.
Pasé demasiado tiempo golpeándome la cabeza contra la pared por este problema.
Aterricé aquí buscando una solución para el caso en el que no uso el enlace de datos. Nada funcionó para mí, pero al final lo conseguí con:
dataGridView.Columns.Clear();
dataGridView.Rows.Clear();
dataGridView.Refresh();
Si usted es el segundo desarrollador más tonto del planeta (yo soy el más tonto), todas las soluciones anteriores parecen funcionar: CellFormatting, DataSourceChanged y RowPrePaint. Prefiero RowPrePaint.
Luché con esto (durante demasiado tiempo) porque necesitaba anular mi SelectionBackColor y SelectionForeColor en lugar de BackColor y ForeColor cuando estaba cambiando la fila seleccionada.
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;
}
}