coloriertes DatagridView (bedingte Formatierung)

    • VB.NET

      coloriertes DatagridView (bedingte Formatierung)

      OwnerDrawing: coloriertes DatagridView

      Anbei eine App mit typisiertem Dataset und 2 DGVs welche datenabhängig coloriert und formatiert sind.
      Die ArtikelDataTable enthält eine Spalte Color As Integer.
      auch enthält die ArtikelTable Grenzwerte (LBound, UBound)
      Im ArtikelDatagridview ist die Schreibweise dieses color-Wertes per DefaultCellstyle auf Hexadezimal formatiert.
      Weiters wird das _CellPainting behandelt, und bei der Color-Spalte wird per Color.FromArgb der Color-Wert auch als BackgroundColor dargestellt.




      Die AnalyseDataTable ist der ArtikelTable untergeordnet, und enthält u.a. die Spalten Param1 und Param2

      Im CellPainting des Grids dieser AnalyseTable werden Param-Werte, die Artikel.Lbound unterschreiten grün hinterlegt, und Werte, die Artikel.UBound überschreiten rot.




      OwnerDrawing
      Hier das Cellpainting des ArtikelDatagridViews (erstes Bildchen):

      VB.NET-Quellcode

      1. Private _NoBackPaintParts As DataGridViewPaintParts = DataGridViewPaintParts.All Xor DataGridViewPaintParts.Background
      2. Private _BackBrush As New SolidBrush(Color.Red)
      3. Private Sub ArtikelDataGridView_CellPainting(ByVal sender As Object, ByVal e As DataGridViewCellPaintingEventArgs) Handles ArtikelDataGridView.CellPainting
      4. If 0 <> (e.State And DataGridViewElementStates.Selected) Then Return
      5. Dim grd = DirectCast(sender, DataGridView)
      6. If e.ColumnIndex <> 2 OrElse Not e.RowIndex.IsBetween(0, grd.RowCount - 2) Then Return
      7. _BackBrush.Color = Color.FromArgb(CInt(e.Value))
      8. e.Graphics.FillRectangle(_BackBrush, e.CellBounds)
      9. e.Paint(e.CellBounds, _NoBackPaintParts)
      10. e.Handled = True
      11. End Sub

      Meine Erklärung geht einfach ZeileFürZeile durch.
      Im Code habich nichts kommentiert, denn wem die Syntax der Sprache vb.net bekannt ist, dem erklärt sich der Code vollständig selbst.
      Und wenn bezüglich einer der auftretenden Klassen oder Enumerationen Unsicherheit besteht, so konsultiert man ja bekanntlich (hoffentlich ;) ) den ObjectBrowser
      1. Die KlassenVariable _NoBackPaintParts erhält einen DataGridViewPaintParts-EnumerationsWert, der festgelegt, wie das DatagridView die Color-Zelle zeichnen soll: Das DGV soll nämlich alles zeichnen, mit Ausnahme des Backgrounds (den willich ja selbst zeichnen)
        Falls unklar ist, warum der Xor - Operator aus .All Xor .Background definiert, das alles ausser dem Background gezeichnet wird, so leseman das Kapitel zu Enumerationen nach im gratis Löffelmann-Buch. Dieses Grundlagen-Thema angemessen zu behandeln würde hier zu weit führen, und dort ist es angemessen behandelt. :thumbup:
      2. Auch als Klassenvariable instanziere ich einen Brush (Pinsel), den ich zum Zeichnen benutzen will.
      3. (leerzeile)
      4. (selbsterklärend: ) Methoden-Deklaration inklusive Handles-Klausel
      5. der State des EventArgs wird geprüft - eine als selektiert ausgewiesene DGV-Zelle soll auf keinen Fall ownergedrawt werden
        e.State ist wie auch _NoBackPaintParts ein Enum-Typ, und daher ist Logik und Syntax der State-Überprüfung gleich mit-verstanden, wenn man das o.g. Kapitel konsultiert hat (glaubts mir: Thema Enums ist Grundlagenwissen ;) )
      6. eine Variable, die den Event-Sender in typisierter Form speichert
        Falls Sinn und Wirkung des Casts nicht bekannt: o.g. Buch lesen - Typumwandlungen sind noch wichtigere Grundlage als Enums
      7. der ownerdrawn Zellbereich wird eingegrenzt: Gezeichnet wird nur am SpaltenIndex 2, und nur DGV-Rows mit RowIndex zwischen 0 und RowCount - 2(!)
        RowCount - 2 schließt die letzte DGV-Row aus, denn das ist eine HinzufügeZeile, die noch gar keine Werte enthält. In dieser letzten DGV-Row den Color-Wert zu zeichnen führte zu Fehlverhalten, denn die Row enthält ja gar keinen Color-Wert.
      8. die Farbe des Pinsels wird festgelegt (wohl selbsterklärend auch für Noob007, odr?)
      9. (ebenfalls selbsterklärend: ) mit dem Pinsel wird der Zellbereich ausgefüllt.
      10. nanu? das Eventargs hat sogar eine Methode .Paint() die man aufrufen kann?
        ja, genau. Steht da doch :D . Die DataGridViewCellPaintingEventArgs erweisen sich hier als für Eventargs ungewöhnlich mächtig - normal erwartet man ja maximal ein paar Daten (zB. die (Mouse-) Location bei MouseEventArgs oder sowas)
        Hierbei ist auch das in #1 zurechtgemachte _NoBackPaintParts anzugeben, damit der Hintergrund nicht übermalt wird.
      11. (selbsterklärender gehts kaum: ) die Handled-Property des Eventargs wird gesetzt.
        Den Sinn vons das kann man sich glaub auch leicht denken: Dadurch wird dem DGV mitgeteilt, dass der Paint-Vorgang für diese Zelle erledigt ist, und unerwünscht ist, dass das DGV anschließend mit seiner internen ZeichenRoutine nochmal drüber geht.



      Fazit
      Das DGV-Cellpaintig-Event stellt einem annähernd alle denkbaren Möglichkeiten bereit, jede einzelne Zelle ganz nach Belieben zu gestalten. Besonders nett dabei, dass man sich auch Teilbereiche zum Selber-Zeichnen rauspicken kann, und den Rest belässt man einfach in der Verantwortung des Standard-ZeichenVorgangs.
      Hier war ja noch einfach - nur die BackColor - ebenso hätte ich den Text zeichnen können, oder Gridlines oder sonstwas.
      Auch mache ichs mir hier einfach, indem ich den Color-Wert direkt aus der DGV-Zelle hole, anstatt über die BindingSource zu gehen, und mir den ganzen Datensatz zu holen.
      Die CellPainting-Routine des anneren Grids leistet in dieser Hinsicht wesentlich mehr und komplexeres.
      Weitere Beispiele von DGV-Ownerdrawing finden sich auf noch ein coloriertes Datagridview und DatagridViewProgressCell
      Dateien
      • AnalyseDB2008.zip

        (35,43 kB, 616 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 11 mal editiert, zuletzt von „ErfinderDesRades“ ()