¿Cómo cambiar el color de la fila en datagridview?

143

Me gustaría cambiar el color de una fila en particular en mi vista de cuadrícula de datos. La fila debe cambiarse a rojo cuando el valor de columnncell 7 es menor que el valor de columnncell 10. ¿Alguna sugerencia sobre cómo lograr esto?

EB.
fuente

Respuestas:

192

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; 
     }
Ricardo Sanchez
fuente
1
Gracias por la ayuda Ricardo. He probado el código que me sugirió. Todavía no puedo hacer que funcione. ¿Te importaría echar un vistazo a este código y decirme dónde me he equivocado? Soy un estudiante principiante de C #. Estoy seguro de que no he escrito el código de comparación correctamente. foreach (fila DataGridView en vendorsDataGridView.Rows) {if (row.Cells [7] .Value is <row.Cells [10] .Value) {dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } Aprecio tu ayuda. EB
EB.
EB Agregué un nuevo código basado en el código que proporcionaste. Tu sintaxis se apagó un poco, prueba el código que acabo de agregar arriba.
Ricardo Sánchez
2
Ricardo ¡Cambié .text a .value y cambié a DefaultCellstyle.Backcolor = color.red y el código funcionó! ¡Gracias por tu tiempo! EB
EB.
60

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 RowPrePaintevento 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;
    }
}
Edén
fuente
3
Realmente me gusta cómo captas el problema desde la raíz en lugar de esperar hasta que todo haya sido pintado. Este es un enfoque muy "fuera de la caja". La mayoría de la gente prefiere simplemente bucle a través de cada fila de nuevo ...
bird2920
Además de ser mucho más rápido, también ayuda hacerlo en el momento adecuado. Tuve problemas con mis filas que no se colorean, probablemente porque configuré el color en el momento equivocado. Con este enfoque, se garantiza que sucederá en el momento correcto.
sanderd17
1
Esto funciona geat. También después de ordenar su actualización de manera correcta.
macmuri
24

Estás buscando el CellFormattingevento.
Aquí hay un ejemplo.

SLaks
fuente
2
La diferencia con este enfoque es que cada celda se comparará en lugar de solo una. Puede ser un problema de rendimiento si tiene varios cientos de celdas.
Ricardo Sanchez
21

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 DataBindingsCompletepara DataGridView. Después de eso funcionó.

Espero que esto ayude a las personas que enfrentan el mismo problema.

usuario1614017
fuente
el color del texto no cambia cuando se activa la anulación onLoad (..) o el evento. DataBindingsComplete es un lugar mucho mejor para configurar el color de las filas.
timothy
13

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;
}
Demi
fuente
Gracias por tu ayuda. Su sugerencia es la más cercana que he llegado a resolver el problema. Pero sigo recibiendo el error que dice que "Valor" no existe en contexto o "Celdas" no existe en contexto. Tratando de resolverlo ...
EB.
esta línea de código (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) ahora me da este error El operador '<' no se puede aplicar a operandos de tipo 'objeto' y 'objeto'
EB.
Lánzalos a Integer, entonces. :-) algo como: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Demi
8

Algunas personas les gusta usar las Paint, CellPaintingo CellFormattingeventos, 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 CellFormattinges que solo se llama en celdas visibles, por lo que no tiene que formatear celdas no visibles, sino que las formatea varias veces.

Denise Skidmore
fuente
5

Puede cambiar Backcolorfila por fila utilizando su condition.and esta llamada de función después de la aplicación Datasourcede 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;
    }
}
Pratik 1020
fuente
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;                   
    //    }
    //}
}
Christopher
fuente
2

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

        }

    }
}
daniele3004
fuente
1

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;
            }
        }
granadaCoder
fuente
0

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;
    }
}
Edison
fuente
1
Se le solicita DatagridView en la aplicación de Windows. Y su respuesta es sobre GridView of Web.
Pratik 1020
0

Funciona en Visual Studio 2010. (¡Lo probé y funciona!) Pintará toda tu fila.

  1. Crea un botón para el datagridview.
  2. Cree un CellClickevento 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;
}
Levi
fuente
0

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.

Harshal Doshi Jain
fuente
0

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;
                    }
                 }
bencemik95
fuente
0

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.

ulatekh
fuente
0

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();
Gogu CelMare
fuente
0

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.

Encadenar
fuente
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;
    }
}
Amit Patil
fuente