Laden...

Zelle in Datagridview in Abhängigkeit des Zellenwertes rot einfärben

Erstellt von jaschi vor 4 Jahren Letzter Beitrag vor 4 Jahren 2.551 Views
J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren
Zelle in Datagridview in Abhängigkeit des Zellenwertes rot einfärben

Hallo,

ich bin ein Neuling in c#.
Meine Frage lautet:
Wie bekomme ich es hin bei
row.Cells["Column5"].Value = Flags[0]
bis
row.Cells["Column5"].Value = Flags[3]
in Abhängigkeit des Wertes der Zelle die Zelle zu färben.
Die Zellen sollen bei dem Wert 1 sich rot werden.
Ich hoffe, dass ich mich verständlich ausgedrückt habe.
Es gibt ja schon mehrere Wege zu diesem Thema aber ich bekomme es nicht gebacken.

Vielen Dank für eure Hilfe.

Der Code lautet momentan wie folgt.



                            int rowId = ListFlags.Rows.Add();
                            // Grab the new row!
                            DataGridViewRow row = ListFlags.Rows[rowId];
                                    if (Identifier != null)

                            // Add the data

                            {
                               
                                    row.Cells["Column1"].Value = Identifier;
                                    row.Cells["Column2"].Value = name1[0];
                                    row.Cells["Column3"].Value = InstanceNumber;
                                    row.Cells["Column4"].Value = Description;
                                    row.Cells["Column5"].Value = Flags[0];
                                    row.Cells["Column6"].Value = Flags[1];
                                    row.Cells["Column7"].Value = Flags[2];
                                    row.Cells["Column8"].Value = Flags[3];
                            }
                                    else

                                    row.Cells["Column1"].Value = "";
                                    row.Cells["Column2"].Value = name1[0];
                                    row.Cells["Column3"].Value = InstanceNumber;
                                    row.Cells["Column4"].Value = Description;
                                    row.Cells["Column5"].Value = Flags[0];
                                    row.Cells["Column6"].Value = Flags[1];
                                    row.Cells["Column7"].Value = Flags[2];
                                    row.Cells["Column8"].Value = Flags[3];
                          
 

Frischling

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Vielen Dank für Deine Antwort Abt

Ich habe natürlich auch gegoogelt und versucht verschiedene Lösungen zu benutzen aber es hat nichts funktioniert.
Ich weiß nicht genau, wo ich die Zeilen einfügen muss.
Deshalb brauche ich Hilfe.
Ich hoffe, dass ich diese auch bekomme.

Gruß

jaschi

Frischling

16.806 Beiträge seit 2008
vor 4 Jahren

🤔 musst prinzipiell nur machen, was da auf Stackoverflow zu finden ist.

CellFormatting ist ein Event der DataGridView, das Du eben abonnieren musst.
Also nen bisschen Doku musst schon auch selbst lesen, wenn Dir was unklar ist 🙂

DataGridView.CellFormatting Event
Die Doku hat auch eine ausführliche Erklärung und Beispiele. Schau bitte zuerst in die Doku, wenn Dir was unklar ist und bitte erwarte nicht, dass wir das jetzt für Dich schreiben.

Das Forum schubst Dich in die richtige Richtung und zeigt Dir, wie Du das Problem löst.
Aber das Forum schreibt Dir nicht Dein Code - sorry 🙂

Ansonsten musst eben mal ne konkrete Frage stellen, was Du versuchst und wo Du nicht weiter kommst.

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo Abt,

erstmal vielen Dank für deine Antwort und deinen Tip mit dem CellFormatting Event.
Ich habe jetzt lange versucht die Formatierung zu machen.
Jetzt bin am verzweifeln und brauche etwas "Hilfe".
Wenn ich if (Convert.ToInt16(row.Cells["Column5"].Value) == 1) programmiere bleiben alle Zellen weiß,
obwohl eine "1" in einer Zelle der Spalte 5 steht.
Bei Eingabe von !=0 wierden alle Zellen rot beim Inhalt von "0" oder "1".


 private void ListFlags_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            {
                foreach (DataGridViewRow row in ListFlags.Rows)
                {
                    if (Convert.ToInt16(row.Cells["Column5"].Value) == 1)
               //   if (Convert.ToInt16(row.Cells["Column5"].Value) != 0)
                    {
                        row.Cells["Column5"].Style.BackColor = Color.Red;
                    }
                    else
                        row.Cells["Column5"].Style.BackColor = Color.White;
                 }
            }
        }

Gruß jaschi

Frischling

16.806 Beiträge seit 2008
vor 4 Jahren

Dann debugge Deinen Code erst [Artikel] Debugger: Wie verwende ich den von Visual Studio? mal und schau selbst, ob überhaupt die Code Stelle erreicht wird, wie Du es Dir denkst...
Selbstständig den Code debuggen sollte immer das aller erste sein, was Du machst.

ToInt16 sieht nicht nach dem aus, was Du vermutlich vor hast.
Vermutlich suchst Du int.Parse oder ToInt32 (oder noch besser int.TryParse()).
Prinzipiell sollte Convert.ToInt16(1) == 1 aber True liefern; schau Dir also mal die Werte an - ob da wirklich das drin steht, was Du denkst... vermutlich nicht.

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo Abt,

Du hast schon recht, dass ich ganz am Anfang stehe.
Debuggen kann ich den Code leider nicht, da es sich um ein Plugin handelt und beim Drücken von F5 eine *.dll erstellt wird.
Erst wenn ich das Hauptprogramm ausführe stelle ich fest, ob es funktioniert.
Auch mit ToInt32 funktioniert es nicht.
Ich habe dir mal einen screenshot mitgeschickt.

Gruß jaschi

Frischling

H
523 Beiträge seit 2008
vor 4 Jahren

Debuggen kann ich den Code leider nicht, da es sich um ein Plugin handelt und beim Drücken von F5 eine *.dll erstellt wird.

Du kannst die DLL auch debuggen, wenn Dir der Code des Projektes, welches die DLL aufruft nicht vorliegt: https://docs.microsoft.com/de-de/visualstudio/debugger/debugging-dll-projects?view=vs-2019#vxtskdebuggingdllprojectsthecallingapplication

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo hypersurf,

ich habe einen Haltepunkt eingefügt.
Aber egal ob ich F5, F10 oder F11 drücke, es wird jedes mal eine neue dll erzeugt , siehe screenshot.
Was mach ich falsch?

Gruß jaschi

Frischling

H
523 Beiträge seit 2008
vor 4 Jahren

Der Link den ich gepostet habe verrät Dir, wie Du eine DLL debuggen kannst ohne den Quellcode des aufrufenden Projektes zu besitzen.

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Da bin ich als Neuling überfordert.
Vielleicht kannst Du mir einen Tip geben, um mein Problem (siehe screenshot oben) zu lösen.

Gruß jaschi

Frischling

16.806 Beiträge seit 2008
vor 4 Jahren

Ob Du jetzt Neuling bist oder nicht - das ändert die Sache nicht, dass Du selbst wissen musst zu debuggen.
Ohne das wirds ganz arg schwer. Du musst Dich mit den Grundlagen beschäftigen - von C# und Visual Studio.
Das kann Dir hier leider niemand abnehmen. 😉

Wir hier können alle nicht hellsehen, wir haben keine Glaskugel. Leider.
Wir können nicht sehen, ob das if hier überhaupt erfolgreich ist oder nicht; auch nicht welche Value wirklich in der Zeile steckt.

Das kannst nur Du ganz alleine mit Debugging.
Und wir alle mussten da als Neulinge durch und lernen wie man debuggt. =)

Zum Thema Links noch.
Ich hab Dir den Link zur Dokumentation vom CellFormatting Event geben, damit Du verstehst, was der Event macht und Dir das Beispiel anschaust.
Weil das Beispiel zeigt eine weitere Lösung; im Prinzip inhaltlich genau das macht, was Du hier vorhast. Ich vermute, dass Du es Dir nicht angeschaut hast 😦

Mach es, wie es das verlinkte Beispiel zeigt:

  • Nimm die Zeileninformation aus den Event Args
  • Zieh die Value aus diesen Zeileninformationen
  • Färbe die Zeile, wie es das Beispiel zeigt
        private void ListFlags_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (dataGridView1.Columns[e.ColumnIndex].Name == "Column5") // oder was auch immer der echte Zellenname ist
            {
                if (e.Value != null)
                {
                    if (int.TryParse(e.Value as string, out int cellValue))
                    {
                        if (cellValue != 0)
                        {
                            e.CellStyle.BackColor = Color.Red;
                            return;
                        }
                    }
                }

                e.CellStyle.BackColor = Color.White;
            }
        }

Und denk auch dran das Event zu abonnieren.....

Wenn Dir etwas unklar ist, schaue bitte zuerst mal in die Doku - und auch nochmal in die Grundlagen. [FAQ] Wie finde ich den Einstieg in C#?

Du wirst ganz vieles nicht verstehen und nicht alleine weiter kommen, wenn Du die Grundlagen von C#, der Doku oder Visual Studio nicht verstehst - wir haben alle mal als Neulinge angefangen.
Aber wir können Dir einfach das Debugging nicht übernehmen. So weit sind die Erfinder der Glaskugel einfach noch nicht.

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo Abt,

vielen Dank für deine Antwort. Ich habe es gemäß dem Beispiel gemacht. Aber es hat nicht geklappt.
Erst kam eine Fehlermeldung bei

if (int.TryParse(e.Value as string, out** int cellValue**

Dies habe ich dann in
int cellValue;
if (int.TryParse(e.Value as string, out cellValue))
geändert dann war die Fehlermeldung weg.

Das CellFormatting ist im StausFlag.Desgner abonniert.
this.ListFlags.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.ListFlags_CellFormatting);

Aber es hat immer noch nicht funktioniert.
Hier der Code



 private void ListFlags_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
        foreach (DataGridViewRow row in ListFlags.Rows)
        {
          if (ListFlags.Columns[e.ColumnIndex].Name == "In Alarm") // oder was auch immer der echte Zellenname ist
          {
              if (e.Value != null)
              {
                        int cellValue;
                        if (int.TryParse(e.Value as string, out cellValue)) 
                  {
                      if (cellValue != 0)
                      {
                          e.CellStyle.BackColor = Color.Red;
                          return;
                      }
                  }
              }
                    e.CellStyle.BackColor = Color.Wheat;
          }
      }
      }


Ich habe dann noch die Farbe von Color.White in Color.Wheat geändert um zu sehen, ob überhauot etwas passiert. Aber auch hier haben sich die Zellen nicht gefärbt.

Ich lasse es jetzt sein. Anscheinend ist es ein gößeres Problem mit dem plugin und dem Hauptprogramm, welches nicht so einfach zu lösen ist.

Trotzdem nochmals vielen Dank für deine Bemühungen.
Anbei ist noch ein screenshot wo das einfärben funktioniert.
Gruß jaschi

Frischling

4.931 Beiträge seit 2008
vor 4 Jahren

Passen denn die Datentypen der Zellen (Spalte)?
In deinem ersten Beitrag benutzt du ja nur string als Value, für den In_Alarm-Code werden aber Zahlen (int) benutzt. Oder welchen Datentyp haben Flags[x]?

PS: Außerdem, was soll die unnötige erste Zeile foreach (DataGridViewRow row in ListFlags.Rows)?
CellFormatting wird für jede Zelle einzeln aufgerufen, du benötigst dort keine Schleife über alle Zeilen.

H
523 Beiträge seit 2008
vor 4 Jahren

Ich lasse es jetzt sein. Anscheinend ist es ein gößeres Problem mit dem plugin und dem Hauptprogramm, welches nicht so einfach zu lösen ist.

Hast Du das Problem denn mal debuggt? Beim Debuggen siehste direkt ob das Problem an Deinem Plugincode liegt oder nicht.


>

16.806 Beiträge seit 2008
vor 4 Jahren

Anscheinend ist es ein gößeres Problem mit dem plugin und dem Hauptprogramm, welches nicht so einfach zu lösen ist.

Das Problem ist, dass man dir auf mehrere Arten versucht zu helfen; und Du dann irgendwas machst.
Du kopierst offenbar blind irgendwelchen Code zusammen, den Du selbst nicht verstehst - und wunderst Dich, dass es nicht klappt.
Das kann natürlich nur gegen die Wand fahren. So hab ich aber auch keine Lust mehr Dir zu helfen... 👍

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo Th69,

ich habe jetzt den Code geändert.



                if (ListFlags.Columns[e.ColumnIndex].Name == "In Alarm") // oder was auch immer der echte Zellenname ist
                {
                    if (e.Value != null)
                    {
                        int cellValue = 1;
                        int cellValue1 = 1;

                      //  if (int.TryParse(e.Value as string, out cellValue))
                        {
                            if (cellValue == cellValue1)
                            {
                                e.CellStyle.BackColor = Color.Red;
                                return;
                            }
                        }
                    }
                          e.CellStyle.BackColor = Color.Wheat;
                }


Jetzt ist doch if (cellValue == cellValue1) = true und es müsste die nächste Zeile abgearbeitet werden und die Zellen der Spalte "In Alarm" rot eingefärbt werden.
Aber es geht nicht.
Wie schon Abt mehrmals erwähnt hat habe ich nicht viel Ahnung.
Vielleicht kannst Du mir erklären wieso das nicht geht, ggfs. kann ich dir mal den Code des Plugins schicken.

Danke im voraus
Gruß jaschi

Frischling

16.806 Beiträge seit 2008
vor 4 Jahren

Ich tipp noch drauf, dass Du den Event gar nicht abonniert hast.
Könntest binnen Sekunden mit Debugging heraus finden...aber hier weigerst Du Dich ja renitent - obwohl man Dir Anleitungen an die Hand gibt.
Gerne nochmal: [Artikel] Debugger: Wie verwende ich den von Visual Studio?

Wenn Du Dich selbst nicht in der Lage siehst das grundlegende Debugging zu beherschen, dann mach es eben mal mit einfachen Elementen, bei denen man die Reaktion sieht.
Helf Dir doch mal ein wenig selbst und hoff nicht auf ein Wunder...

      private void ListFlags_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            MessageBox.Show("Event wird aufgerufen", "Debugging", MessageBoxButtons.OK);

            if (ListFlags.Columns[e.ColumnIndex].Name == "In Alarm") // oder was auch immer der echte Zellenname ist
            {
                MessageBox.Show("Zelle " + e.ColumnIndex + " ist eine Alarm-Zelle", "Debugging", MessageBoxButtons.OK);

                if (e.Value != null)
                {
                    MessageBox.Show("Wert der Zelle gefunden", "Debugging", MessageBoxButtons.OK);
                    int cellValue = 1;
                    int cellValue1 = 1;

                    //  if (int.TryParse(e.Value as string, out cellValue))
                    {
                        if (cellValue == cellValue1)
                        {
                            MessageBox.Show("Färbe Zelle Rot", "Debugging", MessageBoxButtons.OK);

                            e.CellStyle.BackColor = Color.Red;
                            return;
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Kein Wert der Zelle gefunden", "Debugging", MessageBoxButtons.OK);
                }

                MessageBox.Show("Färbe Zelle Weiß", "Debugging", MessageBoxButtons.OK);
                e.CellStyle.BackColor = Color.White;
            }
        }

Aber bitte hör auf die Aufgaben auf das Forum abzuwälzen. Wir sind nicht Deine Fehlerbeseitiger.
[Hinweis] Wie poste ich richtig?
Ansonsten müssen wir hier eben dicht machen.

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo Abt,

es tut mir Leid dass ich dich am Rande eines Herzinfarktes hinführe.
Aber ich meine mit der Zeile im StatusFlags.Designer.cs

this.ListFlags.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.ListFlags_CellFormatting);

ist das Event abonniert, oder?

Gruß jaschi

PS Über das debugging lese ich mich jetzt richtig ein.

Frischling

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo zusammen,

ich habe es mittlerweile geschafft eine Spalte in Abhängigkeit eines Zellenwertes zu färben, siehe angehängten Code.
Ob es die optimale Lösung weiß ich nicht aber es funktioniert.



//    neu hinzugekommen 29.10.2019
                            string Flags = value[0].Value.ToString();
                            // Zahlenreihe in einzelne Ziffern zerlegt.
                            string InAlarm = Flags.Substring(0, 1);
                            string Fault = Flags.Substring(1, 1);
                            string Overridden = Flags.Substring(2, 1);
                            string OOS = Flags.Substring(3, 1);

// dann funktionierte der Lösungsvorschlag von Abt auch - vielen Dank nochmals.

private void ListFlags_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            // Der Name in der runden Klammer kommt von Entwurf(Name) bei Eigenschaften Spalten bearbeiten.
            if (this.ListFlags.Columns[e.ColumnIndex].Name == ("Column8"))
            {
                if (e.Value != null)
                {
                    int cellValue;
                    if (int.TryParse(e.Value as string, out cellValue))
                    {
                        if (cellValue != 0)
                        {
                            e.CellStyle.BackColor = Color.Pink;
                            return;
                        }
                    }
                }
                e.CellStyle.BackColor = Color.White;
            }
        }


Jetzt möchte ich gerne auch die anderen Spalten ebenso gefärbt haben.
Auf der Suche nach einer Lösung habe ich leider nichts gefunden und selbst es nicht geschafft.
Über einen Tip würde ich mich freuen.

Gruß jaschi

Frischling

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo zusammen,

ich habe jetzt doch eine funktionierende Lösung gefunden.


private void ListFlags_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            foreach (DataGridViewRow row in ListFlags.Rows)
            {
                if (Convert.ToInt16(row.Cells["Column5"].Value) == 1)
                {
                    row.Cells["Column5"].Style.BackColor = Color.Pink;
                }
                if (Convert.ToInt16(row.Cells["Column6"].Value) == 1)
                {
                    row.Cells["Column6"].Style.BackColor = Color.Pink;
                }
                if (Convert.ToInt16(row.Cells["Column7"].Value) == 1)
                {
                    row.Cells["Column7"].Style.BackColor = Color.Pink;
                }
                if (Convert.ToInt16(row.Cells["Column8"].Value) == 1)
                {
                    row.Cells["Column8"].Style.BackColor = Color.Pink;
                }
            }
        }

Vielen Dank nochmal für eure Hilfe.
Gruß Jaschi

Frischling

4.931 Beiträge seit 2008
vor 4 Jahren

Da bei dir das Einfärben doch unabhängig von der aktuellen Spalte ist, kannst du einfach den Index abfragen:


// bezogen auf die Spalten in deinem ersten Beitrag (also nur Flags[0] - Flags[3])
if (e.ColumnIndex >= 4) // statt this.ListFlags.Columns[e.ColumnIndex].Name == ("Column8")
{
    // ...
}

Edit: Dies habe ich als Antwort auf deinen vorigen Beitrag geschrieben.
Aber warum denn jetzt schon wieder die unsinnige Schleife? In dem Parameter DataGridViewCellFormattingEventArgs e stehen alle Infos über die aktuelle Zelle.

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren

Hallo Th69,

vielen Dank für deine Antwort.
Genau nach sowas


if (e.ColumnIndex >= 4)

hatte ich gesucht und nichts gefunden.
Wo steht sowas?
Ich habe jetzt deine Lösung umgesetzt, da sie ja schneller ist.

Danke
Gruß jaschi

Frischling

16.806 Beiträge seit 2008
vor 4 Jahren

hatte ich gesucht und nichts gefunden.

Du liest eher nicht die Antworten, sondern kopierst halt einfach blind Code durch die Gegend....

MessageBox.Show("Zelle " + e.ColumnIndex + " ist eine Alarm-Zelle", "Debugging", MessageBoxButtons.OK);

J
jaschi Themenstarter:in
13 Beiträge seit 2019
vor 4 Jahren
[gelöst] Zelle in Datagridview in Abhängigkeit des Zellenwertes rot einfärben

Danke für die Hilfe.

Frischling