Announcement

Collapse
No announcement yet.

Rahmen spezifischer DataGridView-Zellen ändern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Rahmen spezifischer DataGridView-Zellen ändern

    Ich versuche in einer DataGridview bestimmte Spalten zu markieren. Da die Hintergrundfarbe bereits als Darstellungsmerkmal verwendet wird, dachte ich mir, ich könne die entsprechende Spalte dadurch hervorheben, das ich in den Zellen dieser Spalte die linken und rechten Zellrahmen anders setze. Ich finde aber irgendwie nur AdjustCellBorderStyle, das nach Beschreibung aber anscheinend gar nicht aufgerufen werden kann, sondern überschrieben werden muss, wenn man eine eigene Cell-Art implementiert, und zu dem ich wiederum einen Artikel gefunden gefunden habe, dass er nur eine neuen Style zurückliefert, aber nichts setzt. In dem Beitrag wurde auch gesagt, man soll es mit Padding versuchen, aber auch ein
    [highlight=vbnet]
    Dim cell As DataGridViewCell = dgrRow.Cells(affectedCellIndex)
    Dim thisCellStyle As DataGridViewCellStyle = cell.Style
    thisCellStyle.Padding = New Padding(5, 0, 5, 0)
    cell.Style.ApplyStyle(thisCellStyle)
    [/highlight]
    scheint auch nichts zu bringen, das Grid sieht überall gleich aus.

    Einige ergoogelte Artikel scheinen darauf hinzudeuten, dass es gar nicht geht, ohne einen eigenen DataGridViewCell-Typ. Ist eine entsprechende Markierung mit einfachen Mitteln machbar, oder sollte ich eher dazu übergehen, die HeaderCell der entsprechenden Spalte besonders zu formatieren?

    Mit freundlichen Grüßen
    Martin Dietz

  • #2
    Hallo,

    du musst die RowTemplate.Height anpassen damit der Innenabstand sichtbar wird.

    [highlight=vb]
    const CUSTOM_CONTENT_HEIGHT=5
    Me.DataGridView1.RowTemplate.Height += CUSTOM_CONTENT_HEIGHT

    'Bind data to datagridview

    Dim newPadding As New Padding(CUSTOM_CONTENT_HEIGHT, 0, CUSTOM_CONTENT_HEIGHT, 0)
    Me.DataGridView1.Rows(2).Cells(2).Style.Padding = newPadding][/highlight]

    Comment


    • #3
      Es geht darum eine Spalte zu markieren, nicht eine Zeile, daher nützt das vergrößern der Zeilenhöhe wenig, aber auch mit der Spaltenbreite klappt es nicht. Ich habe sogar beim Erstellen der Spalten nun explizit die Spalte um 10 (2x das Padding) verbreitert. Es sieht momentan bei mir so aus:

      [highlight=vbnet]
      Public Class myForm

      Public Sub New()
      InitializeComponent()
      dgrDarstellung.RowTemplate.Height += 10
      ShowGrid()
      End Sub

      Private Sub ShowGrid()
      dgrDarstellung.Rows.Clear()
      dgrDarstellung.Colums.Clear()
      Dim IndexToday as Integer = -1
      [...]
      Dim colIndex As Integer
      For i As Integer = 1 To 30
      colIndex = .Add("ColDay" & i, DayDisplayStart.AddDays(i - 1).Day)
      If DayDisplayStart.AddDays(i - 1).Date = Now.Date Then
      IndexToday = colIndex
      End If
      Next
      colIndex = .Add("ColFrei", "frei ab")
      .Item(colIndex).Width = 65
      If IndexToday > 0 Then .Item(IndexToday).Width += 10
      [...]
      While readData()
      aktKategorie = [...]
      dgrRow = new DataGridViewRow()
      dgrRow.HeaderCell.Value = aktKategorie
      dgrRow.CreateCells(dgrDarstellung)
      [...]
      For affectedCell As Integer = 1 To dgrRow.Cells.Count-2
      dgrRow.Cells(affectedCell).Value = [...]
      dgrRow.Cells(affectedCell).Style.BackColor = [...]
      If affectedCell = IndexToday then
      dgrRow.Cells(affectedCell).Style.Padding = New Padding(5, 0, 5, 0)
      End If
      [...]
      Next
      dgrDarstellung.Rows.Add(dgrRow)
      End While
      End Sub

      [...]
      End Class
      [/highlight]

      Trotzdem sieht die Spalte für die heutigen Informationen genauso aus wie der Rest (bis auf die Breite, aber das fällt nicht auf). Also irgendwo fehlt da noch der Knackpunkt...

      Comment


      • #4
        Der Knackpunkt: bevor die DataGridView eine Zelle zeichnet, wird der DefaultCellStyle der zugehörigen Column in Cell.Style geladen. Das Event CellPainting der DataGridView ermöglicht, einzelne Zellen anders als den Default aussehen zu lassen. Im nachfolgenden Beispiel wird das Padding und die Hintergrundfarbe der Zelle geändert, wenn ihr Inhalt mit einem "E" beginnt. Überschriften bleiben unverändert (e.RowIndex >= 0).


        [highlight=vbnet]
        Public Class myForm
        Private Sub dgrDarstellung_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEvent Args) Handles dgrDarstellung.CellPainting
        If e.RowIndex >= 0 AndAlso e.Value IsNot Nothing AndAlso e.Value.ToString.StartsWith("E") Then
        e.CellStyle.BackColor = GetCellColor(e.RowIndex, e.ColumnIndex)
        e.CellStyle.Padding = New Padding(5, e.CellStyle.Padding.Top, 5, e.CellStyle.Padding.Bottom)
        End If
        End Sub

        ''' <summary>
        ''' Erzeugt eine zufällige Farbe für eine Zelle
        ''' </summary>
        ''' <param name="rowIndex"></param>
        ''' <param name="columnIndex"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function GetCellColor(ByVal rowIndex As Integer, ByVal columnIndex As Integer) As Color
        Static rnd As New Random
        Static colors As New System.Collections.Generic.Dictionary(Of Integer, System.Collections.Generic.Dictionary(Of Integer, Color))
        Dim map As System.Collections.Generic.Dictionary(Of Integer, Color)

        If colors.ContainsKey(rowIndex) Then
        map = colors(rowIndex)
        Else
        map = New System.Collections.Generic.Dictionary(Of Integer, Color)
        colors.Add(rowIndex, map)
        End If
        If Not map.ContainsKey(columnIndex) Then
        map.Add(columnIndex, Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256)))
        End If

        Return map(columnIndex)
        End Function
        End Class[/highlight]

        Comment


        • #5
          Hier das Padding zu setzen hat leider auch nicht geholfen, aber DataGridView.CellPainting war das richtige Stichwort. Ich habe das Beispiel von MS unter diesem Event angepasst, um meine Spalten entsprechend zu markieren. das ganze sieht jetzt so aus:
          [highlight=vbnet]
          Private Sub dgrDarstellung_CellPainting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEvent Args) Handles dgrDarstellung.CellPainting
          If ViewMode = EnumOverviewMode.Month AndAlso e.RowIndex >= 0 AndAlso DayDisplayStart.AddDays(e.ColumnIndex) = Now.Date Then
          Dim newRect As New Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, _
          e.CellBounds.Width - 4, e.CellBounds.Height - 4)
          Dim backColorBrush As New SolidBrush(e.CellStyle.BackColor)
          Dim gridBrush As New SolidBrush(System.Drawing.Color.Red)
          Dim gridLinePen As New Pen(gridBrush, 3)

          Try
          ' Draw the grid lines
          e.Graphics.FillRectangle(backColorBrush, e.CellBounds)
          e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, _
          e.CellBounds.Top, e.CellBounds.Left, _
          e.CellBounds.Bottom)
          e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 3, _
          e.CellBounds.Top, e.CellBounds.Right - 3, _
          e.CellBounds.Bottom)

          ' Draw the text content of the cell, ignoring alignment.
          If Not (e.Value Is Nothing) Then
          e.Graphics.DrawString(CStr(e.Value), e.CellStyle.Font, _
          New SolidBrush(e.CellStyle.ForeColor), e.CellBounds.X + 4, e.CellBounds.Y + 4, _
          StringFormat.GenericDefault)
          End If
          e.Handled = True

          Finally
          gridLinePen.Dispose()
          gridBrush.Dispose()
          backColorBrush.Dispose()
          End Try

          End If
          End Sub
          [/highlight]

          Das ist im Prinzip das, was ich ja von vorneherein vor hatte (einfach nur den Rahmen links und rechts einfärben). Schade halt, dass ich das im Endeffekt doch selbst malen muss, aber immer noch besser so, als ich müsse komplett eine eigene DataGridView nachimplementieren, nur um Rahmenfarbe und -breite spezifischer Zellen zu setzen...

          Vielen Dank schöne Ostern (falls kein weiteres Problem vorher auftaucht )
          Martin Dietz

          Comment

          Working...
          X