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?

EB.
quelle

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; 
     }
Ricardo Sanchez
quelle
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;
    }
}
Eden
quelle
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.

SLaks
quelle
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.

user1614017
quelle
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;
}
Demi
quelle
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.

Denise Skidmore
quelle
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;
    }
}
Pratik 1020
quelle
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
quelle
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;
                }
            }

        }

    }
}
daniele3004
quelle
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;
            }
        }
granadaCoder
quelle
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;
    }
}
Edison
quelle
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;
}
Levi
quelle
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.

Harshal Doshi Jain
quelle
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;
                    }
                 }
bencemik95
quelle
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.

ulatekh
quelle
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();
Gogu CelMare
quelle
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.

Jess
quelle
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
quelle