DGV.CellPainting

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    DGV.CellPainting

    Hallo,

    ich hau mir hier irgendwie das Dgv kaputt. Eigentlich sollte die ganze Zeile gefärbt werden, es wird jedoch nur die letzte Spalte gefärbt. Wenn ich eine Zelle selektiere und wieder verlasse, dann wird diese Zelle nachträglich gefärbt falls sie sich in der richtigen Zeile befindet. Heißt im Bild wird beim Anklicken der nächsten Zelle, die, wie zu sehen, noch selektierte Zelle grün. Minimieren-maximieren füllt auch die Zeilen dann. Woran kann das liegen?

    VB.NET-Quellcode

    1. Private Sub dgv1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles dgv1.CellPainting
    2. If 0 <> (e.State And DataGridViewElementStates.Selected) Then Return
    3. If e.ColumnIndex < 0 OrElse e.RowIndex < 0 Then Return
    4. If CInt(dgv1.Rows(e.RowIndex).Cells(2).Value) = CInt(dgv1.Rows(e.RowIndex).Cells(4).Value) Then
    5. e.Graphics.FillRectangle(Brushes.Lime, e.CellBounds)
    6. e.Paint(e.CellBounds, _NoBackPaintParts)
    7. e.Handled = True
    8. Else
    9. Return
    10. End If
    11. End Sub


    Viele Grüße
    hi,
    ich mach das bei mir z.B. im RowPrepaint-Event

    If Not e.RowIndex < 0 AndAlso Not e.RowIndex > dgv.Rows.Count - 1 Then dgv.Rows(e.RowIndex).DefaultCellStyle.ForeColor = Color.Red
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Klappt. Aber warum?

    VB.NET-Quellcode

    1. Private Sub dgv1_RowPrePaint(sender As Object, e As DataGridViewRowPrePaintEventArgs) Handles dgv1.RowPrePaint
    2. If 0 <> (e.State And DataGridViewElementStates.Selected) Then Return
    3. If e.RowIndex < 0 Then Return
    4. If CInt(dgv1.Rows(e.RowIndex).Cells(2).Value) <> CInt(dgv1.Rows(e.RowIndex).Cells(4).Value) Then Return
    5. dgv1.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Lime
    6. End Sub

    CellPainting -> Zelle wird gemalt, nicht die ganze Zeile
    RowPrePaint -> Zeile wird bald gemalt, nicht nur die Zelle

    Eine Zelle muss nur dann neu gezeichnet werden, wenn sie selektiert oder sichtbar wurde. Daher klappt es, wenn sie eben (de)selektiert wird oder das mit Minimieren/Maximieren.
    Klar soweit?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Okay, da ich ja eh die ganze Zeile färbe, macht RowPrePaint wohl mehr Sinn.

    Ich denke das Einfügen der Daten passiert irgendwie parallel zum Zeichnen und da komme ich dann zeitlich mit dem Wertvergleich und dem Event durcheinander. (Zelle 4 gibts noch nicht Zelle3 wurde schon gezeichnet)
    Der DefaultCellStyle umgeht das Problem, weil da vielleicht neu gezeichnet wird?
    Ich habe in der Befüllen-Prozedur der DataTable noch ein dgv1.Invalidate reingemacht, dann funktioniert auch Version aus Post 1
    Der DefaultCellStyle gibt an, wie die Zellen einer Zeile grundsätzlich aussehen soll. Im CellPainting-EventHandler kannst Du davon eben abweichen.
    dgv1.Invalidate führt letztenendes zum Neuzeichnen des DGVs, also wird für jede sichtbare Zelle der CellPainting-EventHandler aufgerufen. Wie Du es machst, kommt auch darauf an, ob die Daten vom User verändern werden können. Wenn nicht, würd ich den DefaultCellStyle setzen. Wenn es live entschieden werden muss, dann den CellPainting-EventHandler nutzen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Jup, darüber habe ich nicht nachgedacht, da ich nie Usereinträge benötige.

    Jedoch was ich meine: Auch die Methode mit dem DefaultCellStyle sollte ja eigentlich den Bedarf zum Neuzeichnen haben.
    Wenn der Wert geschrieben wird, wird die Zelle gezeichnet. Heißt wenn die Werte abgefragt werden vor dem Zeichnen, dann auch vor dem Schreiben, dann sollte logischerweise noch das falsche Ergebnis rauskommen.
    Oder wird die Zeile nach den Zellen gezeichnet? ?(
    Cellpainting -> RowPrePaint -> RowPaint
    Wenn du das DGV als Datengebundenes DGV verwendest (z.B. mit BindingSource als Datenquelle) und veränderst die daran gebundenen Daten, wird das RowPrepaint erneut aufgerufen.
    Ich arbeite viel mit einer Boolean-Spalte "Aktiv" und lass eben alle Einträge mit Aktiv = False mit rotem Text anzeigen. Wenn ich einen Datensatz dann zur Laufzeit auf Aktiv = False
    setze wird aus dem vorher schwarzen Text sofort ein roter -> alles über's RowPrepaint-Event
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Das RowPrepaint heisst RowPrepaint, weil... ja warumwohl.
    Wenn du darin den DefaultCellstyle änderst, dann löst diese Änderung intern ein geeignetes Invalidate(RowDisplayRectAngle) aus, und etwas später wird also das RowDisplayRectAngle neu gezeichnet, mit allen Zellen.
    Was ja Zweck der Übung war.
    Wenn Du wissen willst, welches Event in welcher Reihenfolge kommt: alle Events für ein Control loggen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.