Comment changer la couleur de ligne dans datagridview?

143

Je voudrais changer la couleur d'une ligne particulière dans mon datagridview. La ligne doit être changée en rouge lorsque la valeur de columncell 7 est inférieure à la valeur de columncell 10. Des suggestions sur la façon d'accomplir cela?

EB.
la source

Réponses:

192

Vous devez parcourir les lignes dans le datagridview, puis comparer les valeurs des colonnes 7 et 10 sur chaque ligne.

Essaye ça:

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
la source
1
Merci pour l'aide Ricardo. J'ai essayé le code que vous avez suggéré. Je n'arrive toujours pas à le faire fonctionner. Pourriez-vous jeter un œil à ce code et me dire où je me suis trompé? Je suis un étudiant débutant en C #. Je suis sûr que je n'ai tout simplement pas écrit correctement le code de comparaison. foreach (ligne DataGridView dans vendorsDataGridView.Rows) {if (row.Cells [7] .Value is <row.Cells [10] .Value) {dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } J'apprécie ton aide. EB
EB.
EB J'ai ajouté un nouveau code basé sur le code que vous avez fourni. Votre sintax était un peu éteint, essayez le code que je viens d'ajouter ci-dessus.
Ricardo Sanchez
2
Ricardo. J'ai changé .text en .value et changé en DefaultCellstyle.Backcolor = color.red et le code a fonctionné !!! Merci pour votre temps! EB
EB.
60

J'étais juste en train d'enquêter sur ce problème (donc je sais que cette question a été publiée il y a presque 3 ans, mais peut-être qu'elle aidera quelqu'un ...) mais il semble qu'une meilleure option soit de placer le code dans le RowPrePaint événement afin que vous ne le fassiez pas. doivent parcourir chaque ligne, seulement celles qui sont peintes (donc il fonctionnera beaucoup mieux sur une grande quantité de données:

Joindre à l'événement

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

Le code de l'événement

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;
    }
}
Eden
la source
3
J'aime vraiment la façon dont vous attrapez le problème à la racine au lieu d'attendre que tout ait été peint. C'est une approche très «hors des sentiers battus». La plupart des gens préfèrent boucler à nouveau chaque ligne ...
bird2920
En plus d'être beaucoup plus rapide, cela aide également à le faire au bon moment. J'ai eu des problèmes avec mes lignes ne se colorant pas, probablement parce que j'ai défini la couleur au mauvais moment. Avec cette approche, il est garanti que cela se produira au bon moment.
sanderd17
1
Cela fonctionne très bien. Aussi après avoir trié son rafraîchissement de manière correcte.
macmuri
24

Vous recherchez l' CellFormattingévénement.
Voici un exemple.

SLaks
la source
2
La différence avec cette approche est que chaque cellule sera comparée par opposition à une seule. Cela peut être un problème de performances si vous avez plusieurs centaines de cellules.
Ricardo Sanchez
21

J'ai également eu du mal à changer la couleur du texte - je n'ai jamais vu le changement de couleur.

Jusqu'à ce que j'ajoute le code pour changer la couleur du texte à l'événement DataBindingsCompletepourDataGridView . Après cela, cela a fonctionné.

J'espère que cela aidera les personnes confrontées au même problème.

user1614017
la source
la couleur du texte ne change pas lors du remplacement onLoad (..) ou de l'événement. DataBindingsComplete est un bien meilleur endroit pour régler la couleur des lignes.
timothy
13

Quelque chose comme ce qui suit ... en supposant que les valeurs dans les cellules sont des nombres entiers.

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

non testé, donc excuses pour toute erreur.

Si vous connaissez la ligne particulière, vous pouvez ignorer l'itération:

if (myDGV.Rows[theRowIndex].Cells[7].Value < myDGV.Rows[theRowIndex].Cells[10].Value)
{
  dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
Demi
la source
Merci de votre aide. Votre suggestion est la plus proche que j'ai pu résoudre le problème. Mais j'obtiens toujours l'erreur disant que "Valeur" n'existe pas dans le contexte ou "Cellules" n'existe pas dans le contexte. Essayer de comprendre ...
EB.
cette ligne de code (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) me donne maintenant cette erreur. L'opérateur '<' ne peut pas être appliqué aux opérandes de type 'objet' et 'objet'
EB.
Jetez-les donc en Integer :-) quelque chose comme: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Demi
8

Certaines personnes aiment utiliser les événements Paint, CellPaintingou CellFormatting, mais notez que la modification d'un style dans ces événements provoque des appels récursifs. Si vous l'utilisez, DataBindingCompleteil ne s'exécutera qu'une seule fois. L'argument pour CellFormattingest qu'il est appelé uniquement sur les cellules visibles, vous n'avez donc pas à formater les cellules non visibles, mais vous les formatez plusieurs fois.

Denise Skidmore
la source
5

Vous pouvez changer Backcolorligne par ligne en utilisant votre condition et cet appel de fonction après l'application DatasourcedeDatagridView .

Voici la fonction pour cela. Copiez simplement cela et mettez-le aprè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
la source
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;                   
    //    }
    //}
}
christophe
la source
2

C'est ma solution pour changer la couleur en dataGridView avec 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
la source
1

Si vous vous liez à une (collection) d'objets concrets, vous pouvez obtenir cet objet concret via la propriété DataBoundItem de la ligne. (Pour éviter de vérifier les chaînes magiques dans la cellule et d'utiliser les propriétés "réelles" de l'objet)

Exemple de squelette ci-dessous:

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

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

puis le gestionnaire d'événements et obtenir l'objet concret (au lieu d'un DataGridRow et / ou de cellules)

        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;
            }
        }
grenadeCoder
la source
0

J'aime généralement utiliser l'événement GridView.RowDataBound Event pour cela.

protected void OrdersGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.ForeColor = System.Drawing.Color.Red;
    }
}
Edison
la source
1
Il est demandé DatagridView dans l'application Windows. Et votre réponse concerne GridView of Web.
Pratik 1020
0

Fonctionne sur Visual Studio 2010. (Je l'ai essayé et ça marche!) Il peindra toute votre ligne.

  1. Créez un bouton pour datagridview .
  2. Créez un CellClickévénement et placez la ligne de code suivante à l'intérieur.

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

Vous n'avez pas mentionné comment la valeur est modifiée. J'ai utilisé des fonctionnalités similaires lorsque l'utilisateur entre une valeur. c'est-à-dire entrer et sortir du mode d'édition.

Utilisation de l' événement 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";
        }
    }                               
}

Vous pouvez ajouter une logique pour effacer la notification d'erreur de la même manière.

si dans votre cas, si les données sont chargées par programme, l' événement CellLeave peut être utilisé avec le même code.

Harshal Doshi Jain
la source
0

Avec ce code, vous ne modifiez que la couleur d'arrière-plan des lignes où la valeur de columname est nulle, les autres lignes de couleur restent la couleur par défaut.

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

Juste une note sur le réglage DefaultCellStyle.BackColor... vous ne pouvez pas le définir sur une valeur transparente saufColor.Empty . C'est la valeur par défaut. Cela implique à tort (pour moi, en tout cas) que les couleurs transparentes sont OK. Ils ne sont pas. Chaque ligne que j'ai définie sur une couleur transparente dessine simplement la couleur des lignes sélectionnées.

J'ai passé beaucoup trop de temps à me cogner la tête contre le mur sur cette question.

ulatekh
la source
0

J'ai atterri ici à la recherche d'une solution pour le cas où je n'utilise pas de liaison de données. Rien n'a fonctionné pour moi mais je l'ai finalement obtenu avec:

dataGridView.Columns.Clear(); 
dataGridView.Rows.Clear();
dataGridView.Refresh();
Gogu CelMare
la source
0

Si vous êtes le deuxième développeur le plus stupide de la planète (moi étant le plus stupide), toutes les solutions ci-dessus semblent fonctionner: CellFormatting, DataSourceChanged et RowPrePaint. Je préfère RowPrePaint.

J'ai eu du mal avec cela (pendant trop longtemps) parce que je devais remplacer mes SelectionBackColor et SelectionForeColor au lieu de BackColor et ForeColor pendant que je changeais la ligne sélectionnée.

Jess
la source
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
la source