Results 1 to 9 of 9

Thread: [RESOLVED] DataGridView: Custom vertical gridline color every nth column

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2017
    Posts
    32

    Resolved [RESOLVED] DataGridView: Custom vertical gridline color every nth column

    I'm trying to paint a different vertical gridline color every 4th column on a DataGridView.
    While it works, whenever I scroll horizontally these lines do not persist. I assume that the control doesn't refresh or I am using the wrong event for the custom painting.
    Even If I manually do a refresh (let's say through a button), those custom-lines are out of place, so it seems my approach is all wrong from the beginning.
    Code:
        Private Sub PatGrid_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles PatGrid.RowPostPaint
    
            Dim cl As Integer
            Dim gridpen As New Pen(SystemColors.ControlLight)
            Dim colwidths As Integer = PatGrid.RowHeadersWidth
    
            For cl = 1 To PatGrid.ColumnCount - 1
                colwidths += PatGrid.Columns(cl).Width
                If cl Mod 4 = 0 Then
                    e.Graphics.DrawLine(gridpen, colwidths, 0, colwidths, PatGrid.Bottom)
                End If
            Next cl
    
        End Sub

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,467

    Re: DataGridView: Custom vertical gridline color every nth column

    Use the DGV Paint event. It should repaint every time you scroll...

  3. #3
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,467

    Re: DataGridView: Custom vertical gridline color every nth column

    I haven't tried it with a scrolling DGV, but you need to calculate the relative x positions of the lines, by subtracting the width of the non visible columns

  4. #4
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,467

    Re: DataGridView: Custom vertical gridline color every nth column

    Ok. I gave it a try...

    Code:
    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            For x As Integer = 1 To 50
                DataGridView1.Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = x.ToString})
            Next
            DataGridView1.Rows.Add(50)
        End Sub
    
        Private Sub DataGridView1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles DataGridView1.Paint
            Dim lessBy As Integer = 0
            Dim ColumnWidths(DataGridView1.Columns.Count - 1) As Integer
            Dim toTheLeft As Boolean = True
            For x As Integer = 1 To 50
                If Not DataGridView1.Columns(x - 1).Displayed And toTheLeft Then
                    lessBy -= DataGridView1.Columns(x - 1).Width
                Else
                    toTheLeft = False
                End If
                ColumnWidths(x - 1) = DataGridView1.Columns(x - 1).Width
            Next
            lessBy += DataGridView1.RowHeadersWidth - DataGridView1.FirstDisplayedScrollingColumnHiddenWidth
            For x As Integer = 3 To 49 Step 4
                If DataGridView1.Columns(x).Displayed Then
                    Dim left As Integer = ColumnWidths.Take(x + 1).Sum + lessBy
                    e.Graphics.DrawLine(New Pen(Color.Red, 2), left, 0, left, DataGridView1.Height)
                End If
            Next
        End Sub
    
    End Class

  5. #5

    Thread Starter
    Member
    Join Date
    Dec 2017
    Posts
    32

    Re: DataGridView: Custom vertical gridline color every nth column

    Paul, I can't thank you enough. I tweaked your code to take into account the ColumnCount of my grid and it works perfectly.
    The thing is, I'm trying to understand how it works (noob here). In the first loop, it seems you're storing all column widths in an array and the non displayed column widths in the lessby variable?
    Then in the second loop it seems you do the actual drawing, but i'm not at all familiar with the take command and I also had to import the System.Linq namespace to make it work.
    Is there an alternative to that part of the code, so that I can better understand how it works before diving into that linq stuff?

    Sorry if I'm asking much, it's only because I'd like to understand better.
    Thanks in advance

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,467

    Re: DataGridView: Custom vertical gridline color every nth column

    You're right about the first loop. The LINQ Take method takes a specified number of elements from the columnWidths array, the the Sum method sums the values in those elements.
    You could eliminate the LINQ and just use a loop to find the sum...

  7. #7

    Thread Starter
    Member
    Join Date
    Dec 2017
    Posts
    32

    Re: DataGridView: Custom vertical gridline color every nth column

    Thanks for the very clear explanation! I took a look at the documentation but as soon as I saw terms like "Extension" and "IEnumerable" I was scared away With your words it makes perfect sense!

  8. #8
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    3,046

    Re: DataGridView: Custom vertical gridline color every nth column

    Hi,

    another methode would be to use a Column

    here a sample ...i color every 3 and 6th column

    Code:
    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            DataGridView1.SuspendLayout()
            MakeHeader()
            MakeKalendar(2018)
            DataGridView1.ResumeLayout()
            DataGridView1.AllowUserToAddRows = False
        End Sub
        Private Sub MakeHeader()
            Dim col As New List(Of String)
            col.Add("Jan")
            col.Add("Feb")
            col.Add("Mar")
            col.Add("Apr")
            col.Add("May")
            col.Add("Jun")
            col.Add("Jul")
            col.Add("Aug")
            col.Add("Sep")
            col.Add("Oct")
            col.Add("Nov")
            col.Add("Dez")
            With DataGridView1
                Dim Ft As New Font("Courier New", 9)
                .Font = Ft
                For i As Integer = 1 To 12
                    Dim key As String = "C" & i.ToString("00")
                    .Columns.Add(key, col(i - 1))
                    .Columns(key).Width = 45
                    'set the width you need
                    .Columns.Add(key & "1", "1")
                    .Columns(key & "1").Width = 40
                    .Columns.Add(key & "2", "2")
                    .Columns(key & "2").Width = 40
                    .Columns.Add(key & "3", "3")
                    .Columns(key & "3").Width = 5
                    .Columns.Add(key & "4", "4")
                    .Columns(key & "4").Width = 25
                    .Columns.Add(key & "5", "5")
                    .Columns(key & "5").Width = 25
                    .Columns.Add(key & "6", "6")
                    .Columns(key & "6").Width = 25
    
                Next
                .Rows.Add(31)
            End With
            iniColors()
        End Sub
    
        Private Sub MakeKalendar(ByVal Year As Integer)
            With DataGridView1
                For i As Integer = 1 To 12
                    Dim d As Date = New Date(Year, i, 1)
                    For j As Integer = 1 To Date.DaysInMonth(Year, i)
                        Dim col As Integer = (i - 1) * 7
                        .Rows(j - 1).Cells(col).Value = d.ToString("ddd dd")
                        d = d.AddDays(1)
                    Next
                Next
            End With
        End Sub
    
        Private Sub iniColors()
            Dim RowIndex As Integer = 0
            Dim ColIndex As Integer = 0
            DataGridView1.SuspendLayout()
            For Each dgRow As DataGridViewRow In DataGridView1.Rows
                RowIndex = dgRow.Index
                For Each dgvc As DataGridViewColumn In DataGridView1.Columns
                    If dgvc.HeaderText.Contains("3") _
                    Or dgvc.HeaderText.Contains("6") Then
                        ColIndex = dgvc.Index
                        dgvc.Width = 25
                        dgvc.HeaderCell.Style.Alignment = DataGridViewContentAlignment.TopCenter
                        '  dgvc.HeaderCell.Style.Font = New Font(grdTime.Font, FontStyle.Bold)
                        dgvc.HeaderCell.Style.ForeColor = Color.Blue
                        dgvc.HeaderCell.Style.BackColor = Color.LightYellow
                        DataGridView1.Item(ColIndex, RowIndex).Style.BackColor = Color.LightYellow
                    Else
                        dgvc.Width = 45
                        dgvc.HeaderCell.Style.Alignment = DataGridViewContentAlignment.TopCenter
                        'If CStr(dgRow.HeaderCell.Value) = "" Then
                        '    For i As Integer = 0 To dgRow.Cells.Count - 1
                        '        dgRow.Cells(i).Style.BackColor = Color.Gray
                        '    Next
                        '    '    Case Is = 1
                        '    '    For i As Integer = 0 To row.Cells.Count - 1
                        '    '        row.Cells(i).Style.BackColor = Color.CadetBlue
                        '    '    Next
                        '    'End Select
                        'End If
                    End If
                Next
            Next
            DataGridView1.ResumeLayout()
        End Sub
    regards
    Chris
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  9. #9

    Thread Starter
    Member
    Join Date
    Dec 2017
    Posts
    32

    Re: DataGridView: Custom vertical gridline color every nth column

    Thanks for the example Chris. I've used columns as separators in the previous incarnation of my app, written in VB6. While it worked, it was a bit cumbersome having to handle skipping cells when navigating with the arrow keys, or cancelling mouse clicks in those columns, etc.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width