3

How can I find out if column headers are visible in a Datagridview?

Since the Datagridview control does not draw in a disabled state when disabled I am trying to emulate this by drawing a little lock icon in the top-left corner. Since this looks bad if drawn over the column headers I want to move it under them.

I found however that neither the ColumnHeadersVisible nor the ColumnHeadersHeight properties give accurate values in all cases. Sometimes they do at first, but after data is added and removed the property is wrong again for example.

This can be easily reproduced by adding the following class to a new project, running the project once and adding the NewDGV control to the form. Even in the Designer you can see that the rectangle is drawn at the wrong location.

Public Class NewDGV
    Inherits DataGridView

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        
        Dim y As Integer = 0
        'Get the location to draw a rectangle to
        If Me.ColumnHeadersVisible Then
            'y = Me.ColumnHeadersHeight + 1 gives the wrong value as well
            y = Me.GetCellDisplayRectangle(-1, -1, False).Height + 1
        Else
            y = 1
        End If
        e.Graphics.FillRectangle(Brushes.Azure, 1, y, 30, 30)
    End Sub
End Class

Here is the result without further modification:

enter image description here

As you can see, even though the headers are clearly invisible (there aren't actually any columns there anyways), the rectangle is drawn at the wrong location.

Edit: I may not have been entirely clear: Whenever the column headers are invisible I want the rectangle to appear in the upper left corner without extra space to the top. When column headers are visible I want the rectangle to appear below the header cells (meaning being drawn with ColumnHeadersHeight pixels distance from the top).

How can I fix that and find if the column headers are really visible?

Answers in both VB.NET or C#, whichever you prefer, are much appreciated.

Community
  • 1
  • 1
Jens
  • 6,275
  • 2
  • 25
  • 51
  • Have you tried checking on the Columns.Count? – TaW Jul 20 '15 at 19:02
  • @TaW That's actually a good workaround I haven't thought about and I think it works. So the `ColumnHeadersVisible` does not seem to take that into account. Wouldn't be WinForms without fiddling ;-) – Jens Jul 20 '15 at 19:14
  • I think that you should change your approach by defining a Lock PictureBox over the DataGridView and controlling its Visible property. – Graffito Jul 20 '15 at 21:20
  • I'm afraid that does not have anything to do with the question @Graffito . – Jens Jul 20 '15 at 21:29

1 Answers1

1

Not sure if this works under all circumstances - check the FirstDisplayedCell property:

  Protected Overrides Sub OnPaint(e As PaintEventArgs)
    MyBase.OnPaint(e)
    Dim y As Integer = 0
    'Get the location to draw a rectangle to'
    If Me.ColumnHeadersVisible And Me.FirstDisplayedCell IsNot Nothing Then
      '                        ---------------------------------------
      ' 
      y = Me.GetCellDisplayRectangle(-1, -1, False).Height + 1
    Else
      y = 1
    End If
    e.Graphics.FillRectangle(Brushes.Azure, 1, y, 30, 30)
  End Sub
Jens
  • 6,275
  • 2
  • 25
  • 51
SSS
  • 4,807
  • 1
  • 23
  • 44
  • Thank you for your input. I think this might be equivalent to checking `ColumnCount` and `RowCount`. The question is what happens when no data and just columns are present in the DGV. It will probably return the header cell correctly, but this needs to be tested I guess. – Jens Jul 21 '15 at 10:12