none
DatagridView, CellPainting - Erscheinungsbild von Text RRS feed

  • Frage

  • Hallo zusammen,
    ich komme nochmal mit einem Problem zum CellPaintng beim Datagridview. Ich erstelle ein ungebundenes DGV wobei ich Column- und RowHeader individuell mit der DrawString-Methode erzeuge. Ich geh enicht weiter aufs Detail ein. Ich erhalte folgendes Ergebnis:

    Das Problem ist, dass, obwohl die Texte im ColumnHeader mit derselben Methode geschrieben werden wie die Texte der RowHeader, das Erscheinungsbild unterschiedlich ist. Die Columnheader sind fast unleserlich, zusammengequetscht.

    Beide Textarten erzeuge ich mit
                With e.Graphics
                    .TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
    ........

    Wie kann man das Schriftbild der vertikalen Texte verbessern?

    Grüße-


    Dietrich

    Mittwoch, 24. April 2019 17:46

Antworten

  • Nun schaut euch mal das an:

    Sieht doch schon besser aus und ist auch besser lesbar.

    Und dabei ist es nur ein einfacher Trick:
            Dim dFont As Font = dgEntf.ColumnHeadersDefaultCellStyle.Font
    ist die Feststellung des verwendeten Fonts für die Columnheaders.
    Im CellPaintng-Ereignis mache ich nun u.a.:
    e.Graphics.DrawString(e.Value, New Font(dFont.FontFamily, dFont.Size + 1.7),  Brushes.White, 5, 10, sf)

    Und so erhalte ich NUR durch die geringe Vergrößerung des Fonts um 1.7 diese bessere Darstellung der vertikalen Texte!!

    Grüße-


    Dietrich

    • Als Antwort markiert dherrmann Donnerstag, 25. April 2019 14:01
    Donnerstag, 25. April 2019 14:01

Alle Antworten

  • Hallo,

    das geschilderte Verhalten lässt sich z.B. auch in Excel ganz leicht nachstellen. Obwohl die Schriftart und -größe identisch sind, werden die Zeilen- und Spaltenüberschrift doch so unterschiedlich dargestellt.

    Erstaunlicherweise sind die Unterschiede tatsächlich nicht mal so groß: Ich habe dann mal von dem Excel-Blatt einen Screenshot gemacht und in Paint eine Spaltenüberschrift wieder gedreht und über die passende Zeilenüberschrift gelegt. Die Unterschiede sind dann (vermutlich) auf Kantenglättung zurückzuführen (und damit beim Grafiktreiber zu suchen?).

    Interessant auch: Wenn ich bei Excel den Zoom auf 175% oder 200% stelle und dann wieder eine Spaltenüberschrift drehe, sind die Unterschiede verschwindend gering.

    Ich kann die hier leider keine Lösung/Lösungsansatz bieten, zumal das Problem vermutlich nicht an der Programmierung oder an Parametern hängt, aber vielleicht hilft die Info ja doch irgendwie weiter.

    Viele Grüße


    Donnerstag, 25. April 2019 06:04
  • Hi Dietrich,
    der Effekt resultiert aus den Umsetzung der Zeichen in Pixel, die horizontal und vertikal dann anders wirken. Je größer Fontsize und auch Bildschirmauflösung, desto geringer der Unterschied. Mit meiner Demo kann ich das Verhalten nachvollziehen:

    Public Class Form1
    
      Private WithEvents dgv As New DataGridView With {.Dock = DockStyle.Fill, .AllowUserToAddRows = False,
          .VirtualMode = True, .ColumnCount = 5, .RowCount = 5}
    
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Controls.Add(dgv)
        LoadDataGridView()
      End Sub
    
      Private headers As New List(Of String)(New String() {"Aachen", "Augsburg", "Bayreuth", "Berchtesgaden", "Berlin"})
      Private werte1(,) As Integer = New Integer(,) {{0, 2, 3, 4, 5}, {0, 0, 4, 5, 6}, {0, 0, 0, 6, 7}, {0, 0, 0, 0, 8}, {0, 0, 0, 0, 0}}
      Private werte2(,) As Double = New Double(,) {{0, 0, 0, 0, 0}, {1.1, 0, 0, 0, 0}, {2.2, 3.3, 0, 0, 0}, {4.4, 5.5, 6.6, 0, 0}, {7.7, 8.8, 9.9, 10.1, 0}}
    
      Private Sub LoadDataGridView()
        With dgv
          For i = 0 To 4
            .Columns(i).Width = 30
            .Rows(i).Height = 25
          Next
          .RowHeadersWidth = 120
          .ColumnHeadersHeight = 130
        End With
      End Sub
    
      Private Sub dgv_CellValueNeeded(sender As Object, e As DataGridViewCellValueEventArgs) Handles dgv.CellValueNeeded
        If e.ColumnIndex > e.RowIndex Then e.Value = werte1(e.RowIndex, e.ColumnIndex).ToString
        If e.ColumnIndex < e.RowIndex Then e.Value = werte2(e.RowIndex, e.ColumnIndex).ToString
      End Sub
    
      Private Sub dgv_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles dgv.CellPainting
        Dim rahmen As New Pen(Color.Gray, 0.1)
        With e.Graphics
          If e.RowIndex = -1 AndAlso e.ColumnIndex >= 0 Then
            .ResetTransform()
            .TranslateTransform(e.CellBounds.Left + e.CellBounds.Width, e.CellBounds.Top + e.CellBounds.Height)
            .RotateTransform(-90)
            Using strFormat As New StringFormat() With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center}
              Dim rec As New Rectangle(0, -e.CellBounds.Width, e.CellBounds.Height, e.CellBounds.Width)
              .FillRectangle(Brushes.White, rec)
              .DrawRectangle(rahmen, New Rectangle(New Point(rec.Location.X + 1, rec.Location.Y - 1), New Size(rec.Width, rec.Height)))
              Using fnt As New Font(Me.Font.FontFamily, 12)
                .DrawString(headers(e.ColumnIndex), fnt, Brushes.Black, rec, strFormat)
              End Using
            End Using
            .ResetTransform()
            e.Handled = True
          ElseIf e.RowIndex >= 0 AndAlso e.ColumnIndex = -1 Then
            .FillRectangle(Brushes.White, e.CellBounds)
            .DrawRectangle(rahmen, New Rectangle(New Point(e.CellBounds.Location.X, e.CellBounds.Location.Y - 1), New Size(e.CellBounds.Width - 1, e.CellBounds.Height)))
            Using fnt As New Font(Me.Font.FontFamily, 12)
              .DrawString(headers(e.RowIndex), fnt, Brushes.Black, e.CellBounds.Location)
            End Using
            e.Handled = True
          End If
        End With
        rahmen.Dispose()
      End Sub
    End Class

    Das sieht dann so aus (unter der Lupe)


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    • Als Antwort vorgeschlagen Peter Fleischer Donnerstag, 25. April 2019 14:37
    Donnerstag, 25. April 2019 07:03
  • Vielen Dank Christoph und Peter für die Hinweise!!!
    Den "Peter-Code" werde ich mal ausprobieren und meinen eventuell entsprechend ändern/ergänzen.

    Grüße-


    Dietrich

    Donnerstag, 25. April 2019 07:30
  • Nun schaut euch mal das an:

    Sieht doch schon besser aus und ist auch besser lesbar.

    Und dabei ist es nur ein einfacher Trick:
            Dim dFont As Font = dgEntf.ColumnHeadersDefaultCellStyle.Font
    ist die Feststellung des verwendeten Fonts für die Columnheaders.
    Im CellPaintng-Ereignis mache ich nun u.a.:
    e.Graphics.DrawString(e.Value, New Font(dFont.FontFamily, dFont.Size + 1.7),  Brushes.White, 5, 10, sf)

    Und so erhalte ich NUR durch die geringe Vergrößerung des Fonts um 1.7 diese bessere Darstellung der vertikalen Texte!!

    Grüße-


    Dietrich

    • Als Antwort markiert dherrmann Donnerstag, 25. April 2019 14:01
    Donnerstag, 25. April 2019 14:01