Wie ändere ich die Zeilenfarbe in der Datagrid-Ansicht?


143

Ich möchte die Farbe einer bestimmten Zeile in meiner Datagrid-Ansicht ändern. Die Zeile sollte in Rot geändert werden, wenn der Wert von Spaltenzelle 7 kleiner als der Wert in Spaltenzelle 10 ist. Gibt es Vorschläge, wie dies erreicht werden kann?

Antworten:


192

Sie müssen die Zeilen in der Datagrid-Ansicht durchlaufen und dann die Werte der Spalten 7 und 10 in jeder Zeile vergleichen.

Versuche dies:

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
Vielen Dank für die Hilfe Ricardo. Ich habe den von Ihnen vorgeschlagenen Code ausprobiert. Ich kann es immer noch nicht zum Laufen bringen. Würde es Ihnen etwas ausmachen, sich diesen Code anzusehen und mir zu sagen, wo ich falsch gelaufen bin? Ich bin ein Anfänger C # Student. Ich bin sicher, ich habe den Vergleichscode einfach nicht richtig geschrieben. foreach (DataGridView-Zeile in vendorDataGridView.Rows) {if (row.Cells [7] .Value ist <row.Cells [10] .Value) {dataGridViewTextBoxColumn7.DefaultCellStyle.BackColor = red; } } Ich schätze Ihre Hilfe. EB
EB.

EB Ich habe neuen Code hinzugefügt, der auf dem von Ihnen angegebenen Code basiert. Ihre Sintax war ein bisschen aus, versuchen Sie den Code, den ich oben hinzugefügt habe.
Ricardo Sanchez

2
Ricardo. Ich habe .text in .value geändert und in DefaultCellstyle.Backcolor = color.red geändert und der Code hat funktioniert !!! Vielen Dank für Ihre Zeit! EB
EB.

60

Ich habe gerade dieses Problem untersucht (daher weiß ich, dass diese Frage vor fast 3 Jahren veröffentlicht wurde, aber vielleicht hilft sie jemandem ...), aber es scheint, dass eine bessere Option darin besteht, den Code in das RowPrePaintEreignis einzufügen, damit Sie dies nicht tun müssen jede Zeile durchlaufen, nur diejenigen, die gemalt werden (damit es bei großen Datenmengen viel besser funktioniert:

An die Veranstaltung anhängen

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

Der Ereigniscode

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
Ich mag es wirklich, wie Sie das Problem an der Wurzel erkennen, anstatt zu warten, bis alles gemalt ist. Dies ist ein sehr "out of the box" -Ansatz. Die meisten Leute würden lieber einfach jede Reihe noch einmal
durchgehen

Es ist nicht nur viel schneller, sondern auch hilfreich, es zum richtigen Zeitpunkt zu tun. Ich hatte Probleme damit, dass meine Zeilen nicht gefärbt wurden, wahrscheinlich weil ich die Farbe zum falschen Zeitpunkt eingestellt habe. Mit diesem Ansatz wird garantiert, dass es zum richtigen Zeitpunkt geschieht.
Sanderd17

1
Das funktioniert gut. Auch nach dem Sortieren ist die Aktualisierung korrekt.
Macmuri

24

Sie suchen die CellFormattingVeranstaltung.
Hier ist ein Beispiel.


2
Der Unterschied zu diesem Ansatz besteht darin, dass jede einzelne Zelle im Gegensatz zu nur einer verglichen wird. Es kann ein Leistungsproblem sein, wenn Sie mehrere hundert Zellen haben.
Ricardo Sanchez

21

Ich hatte auch Probleme, die Textfarbe zu ändern - ich habe nie gesehen, wie sich die Farbe geändert hat.

Bis ich den Code hinzugefügt habe, um die Textfarbe des Ereignisses DataBindingsCompletefür zu ändern DataGridView. Danach hat es funktioniert.

Ich hoffe, dies wird Menschen helfen, die vor dem gleichen Problem stehen.


Die Textfarbe ändert sich nicht, wenn in onLoad (..) überschrieben wird oder das Ereignis. DataBindingsComplete ist ein viel besserer Ort, um die Farbeinstellung von Zeilen vorzunehmen.
Timothy

13

So etwas wie das Folgende ... vorausgesetzt, die Werte in den Zellen sind Ganzzahlen.

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

ungetestet, entschuldigt sich also für etwaige Fehler.

Wenn Sie die bestimmte Zeile kennen, können Sie die Iteration überspringen:

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

Danke für Ihre Hilfe. Ihr Vorschlag kommt der Lösung des Problems am nächsten. Aber ich bekomme immer wieder die Fehlermeldung, dass entweder "Wert" nicht im Kontext existiert oder "Zellen" nicht im Kontext existieren. Ich versuche es herauszufinden ...
EB.

Diese Codezeile (dgvr.Cells [7] .Value <dgvr.Cells [10] .Value) gibt mir jetzt diesen Fehler. Operator '<' kann nicht auf Operanden vom Typ 'Objekt' und 'Objekt'
EB

Wirf sie dann auf Integer. :-) so etwas wie: Convert.ToInt32 (dvgr.Cells [7] .Value) <Convert.ToInt32 (dgvr.Cells [10] .Value)
Demi

8

Einige Leute mögen die verwenden Paint, CellPaintingoder CellFormattingEreignisse, aber beachten Sie, dass Sie einen Stil in diesen Ereignissen zu ändern verursacht rekursive Aufrufe. Wenn Sie es verwenden DataBindingComplete, wird es nur einmal ausgeführt. Das Argument dafür CellFormattingist, dass es nur für sichtbare Zellen aufgerufen wird, sodass Sie nicht sichtbare Zellen nicht formatieren müssen, sondern sie mehrmals formatieren.


5

Sie können BackcolorZeile für Zeile unter Verwendung Ihrer Bedingung und dieses Funktionsaufrufs nach dem Anwenden Datasourcevon ändern DatagridView.

Hier ist die Funktion dafür. Kopieren Sie das einfach und legen Sie es danachDatabind

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

Dies ist meine Lösung, um die Farbe mit bindingDataSource in dataGridView zu ändern:

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

Wenn Sie an eine (Sammlung) konkreter Objekte binden, können Sie dieses konkrete Objekt über die DataBoundItem-Eigenschaft der Zeile abrufen. (Um zu vermeiden, dass in der Zelle nach magischen Zeichenfolgen gesucht wird und "echte" Eigenschaften des Objekts verwendet werden)

Skelettbeispiel unten:

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

Bindung an die Datagrid-Ansicht

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

dann die Ereignisbehandlungsroutine und das Abrufen des konkreten Objekts (anstelle einer DataGridRow und / oder von Zellen)

        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

Normalerweise verwende ich dafür gerne das Ereignis GridView.RowDataBound.

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

1
Er wird in der Fensteranwendung nach DatagridView gefragt. Und Ihre Antwort bezieht sich auf GridView of Web.
Pratik 1020

0

Funktioniert mit Visual Studio 2010. (Ich habe es versucht und es funktioniert!) Es wird Ihre gesamte Zeile malen.

  1. Erstellen Sie eine Schaltfläche für die datagridview.
  2. Erstellen Sie ein CellClickEreignis und fügen Sie die nächste Codezeile ein.

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

0

Sie haben nicht erwähnt, wie sich der Wert ändert. Ich habe ähnliche Funktionen verwendet, wenn der Benutzer einen Wert eingibt. dh Aufrufen und Verlassen des Bearbeitungsmodus.

Verwenden des CellEndEdit- Ereignisses von 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";
        }
    }                               
}

Sie können auf ähnliche Weise eine Logik zum Löschen der Fehlerbenachrichtigung hinzufügen.

Wenn in Ihrem Fall Daten programmgesteuert geladen werden, kann das CellLeave- Ereignis mit demselben Code verwendet werden.


0

Mit diesem Code ändern Sie nur die Zeilenrückfarbe, wenn der Spaltennamenwert Null ist. Die Farbe anderer Zeilen ist immer noch die Standardfarbe.

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

0

Nur ein Hinweis zur Einstellung DefaultCellStyle.BackColor... Sie können nur einen transparenten Wert festlegen Color.Empty. Das ist der Standardwert. Das impliziert fälschlicherweise (jedenfalls für mich), dass transparente Farben in Ordnung sind. Sie sind nicht. Jede Zeile, die ich auf eine transparente Farbe eingestellt habe, zeichnet nur die Farbe der ausgewählten Zeilen.

Ich habe viel zu viel Zeit damit verbracht, meinen Kopf wegen dieses Problems gegen die Wand zu schlagen.


0

Ich bin hier gelandet und habe nach einer Lösung für den Fall gesucht, dass ich keine Datenbindung verwende. Nichts hat bei mir funktioniert, aber ich habe es am Ende bekommen mit:

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

0

Wenn Sie der zweitdümmste Entwickler auf dem Planeten sind (ich bin der dümmste), scheinen alle oben genannten Lösungen zu funktionieren: CellFormatting, DataSourceChanged und RowPrePaint. Ich bevorzuge RowPrePaint.

Ich hatte Probleme damit (viel zu lange), weil ich meine SelectionBackColor und SelectionForeColor anstelle von BackColor und ForeColor überschreiben musste, als ich die ausgewählte Zeile änderte.


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;
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.