Search code examples
vb.netdatagridviewheadercelldataview

Using VB.Net, how to control single DataGridView Header cell visibility


Community,

I am developing an app that will use a DatGridView object. I cannot find a property or method to hide the column header text of the checkbox column.

DataGridView Header Cell to hide

Properties I have tried include: DataGridView, DataGridViewColumn, DataGridViewColumn.HeaderCell, DataGridViewColumn.HeaderText, DataGridViewColumnHeaderCell, DataGridViewTopLeftHeaderCell

While debugging with Visual Studio 2022, it reports that myDGV contains 0 columns, yet the datagridview is visible on the form. I am confused.

myDGV Column Count = 0

To summarize the code:

  • Build a datatable named myTable
  • Create a dataview named myView
  • myView = myTable.DefaultView
  • Create a DataGridView named myDGV
  • myDGV.DataSource = myView

Perhaps this code I borrowed from another can shed some light as to why I cannot hide the text, "CheckBoxCol", in the first header cell.

AddReference "System.Data"
AddReference "System.Drawing"
AddReference "System.Xml"
Imports System.Data
Imports System.Drawing
Imports System.Windows.Forms

Public Class FormClass

    ' Form, data table, data view, data grid view, string, integers, property sets
    Public myForm As New Form
    Public myTable As New DataTable
    Public myView As DataView
    Public WithEvents myDGV As New DataGridView
    Public WithEvents btnDone As New Button

    Function BuildBaseTable() As DataTable
        ' Add columns
        myTable.Columns.Add("CheckBoxCol", GetType(Boolean))
        myTable.Columns.Add("Sheet", GetType(String))
        myTable.Columns.Add("Note", GetType(String))
        ' Hide columns
        myTable.Columns("Sheet").ColumnMapping = MappingType.Hidden
        ' Add rows
        myTable.Rows.Add(False, "HEAD",         "ANGLE END FLANGES TO BE SKIP/CONTINUOUSLY WELDED. [one or the other]")
        myTable.rows.add(False, "TAIL",         "ANGLE END FLANGES TO BE SKIP/CONTINUOUSLY WELDED. [one or the other]")
        myTable.rows.add(False, "INTERMEDIATE", "ANGLE END FLANGES TO BE SKIP/CONTINUOUSLY WELDED. [one or the other]")
        ' Return the updated table
        Return myTable
    End Function

    Public Sub btnDone_Click(ByVal sender As System.Object, ByVal E As System.EventArgs)
        myForm.Close
    End Sub

    Public Sub Main()

        ' Format the Done button
        btnDone = New Button
        With btnDone
            .Name = "btnDone"
            .Location = New System.Drawing.Point(50, 50)
            .Text = "Done"
            .AutoSize = True
            .AutoSizeMode = AutoSizeMode.GrowAndShrink
            AddHandler.Click, AddressOf btnDone_Click
        End With

        'Build the basic data table
        BuildBaseTable

        'Create a DataView based on the DataTable
        myView = myTable.DefaultView
        
        ' Sort the data
        myView.Sort = "Sheet"

        ' Format the DataGrid column headers
        With myDGV.ColumnHeadersDefaultCellStyle
            .BackColor = System.Drawing.Color.Navy
            .ForeColor = System.Drawing.Color.White
            .Font = New Font(myDGV.Font, FontStyle.Bold)
        End With

        ' Format the remaining DataGrid properties
        With myDGV
            ' Set property values appropriate for read-only display and limited interactivity. 
            .AutoGenerateColumns = True 'False
            .AutoSize = True
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
            .Dock = DockStyle.Fill
            .RowHeadersVisible = False
            .AllowUserToAddRows = False
            .AllowUserToDeleteRows = False
            .AllowUserToOrderColumns = True
            .AllowUserToResizeColumns = False
            .AllowUserToResizeRows = False
            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None
            .ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
            .EnableHeadersVisualStyles = False
            .MultiSelect = True
            .ReadOnly = True
            .RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing
            .SelectionMode = DataGridViewSelectionMode.CellSelect ' .FullRowSelect

            ' Set selection background color for all the cells.
            .DefaultCellStyle.SelectionBackColor = System.Drawing.Color.DeepSkyBlue
            .DefaultCellStyle.SelectionForeColor = System.Drawing.Color.Black

            ' Set RowHeadersDefaultCellStyle.SelectionBackColor so that its default
            ' value won't override DataGridView.DefaultCellStyle.SelectionBackColor.
            .RowHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.Color.Empty

            ' Set background color for all rows and for alternating rows. 
            ' Value for alternating rows overrides the value for all rows. 
            '.RowsDefaultCellStyle.BackColor = System.Drawing.Color.AntiqueWhite
            '.AlternatingRowsDefaultCellStyle.BackColor = System.Drawing.Color.LightGreen

            ' Set grid color
            .GridColor = System.Drawing.Color.Blue

            ' Set data source
            .DataSource = myView
            '.DataMember = "TableName"          

        End With

        'Format the UserForm
        With myForm
            ' Set up form
            .formborderstyle = FormBorderStyle.Sizable
            '           .FormBorderStyle = FormBorderStyle.FixedToolWindow
            .StartPosition = FormStartPosition.CenterScreen
            .Width = 600
            .Height = 200
            .TopMost = True
            .Text = "Add Drawing Note"
            .Name = "Custom Form 1"
            .IsMdiContainer = False

            'Add controls
            .Controls.Add(myDGV)        'Data grid
            .Controls.Add(btnDone)      'Done button

        End With

        myForm.ShowDialog()

    End Sub

End Class

I removed lines that attempted to use the above Properties, so likely code needs to be added to control that single cell visibility. I can supply the code I tried and the errors, but since myDGV columns=0, all errors would not not be valuable I thought.

Once I get this resolved I can work on checkbox toggling and check their status when user closes the form. Another post for another day.

Thank you for your time and attention. I look forward to your replies.

Regards, Jerry

I tried editing these myDGV Properties, but all reported errors since myDGV appears to have no columns.

  • DataGridView
  • DataGridViewColumn
  • DataGridView.HeaderCell.Value
  • DataGridViewColumn.HeaderCell
  • DataGridViewColumn.HeaderText
  • DataGridViewColumnHeaderCell
  • DataGridViewTopLeftHeaderCell

For example, the following code does not enter the loop since myDGV column count is 0:

For Each column As DataGridViewColumn In myDGV.Columns
    MsgBox("Value: " & Column.HeaderCell.Value & vbLf & _
        "Index: " & Column.Index.ToString)
Next

This code reports out of range: Index was out of range.


Solution

  • The problem you face, is that the datagridview only exists, when showdialog is invoked and has run or better is started.

    You can still change the text, when you catch the Onload from myForm

    First give the datagridview a unique name for the Form

        With myDGV
            ' Set property values appropriate for read-only display and limited interactivity. 
            .AutoGenerateColumns = True 'False
            .AutoSize = True
            .Name = "MyDgv"  '<-- add name
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
    

    Then add the eventhandler

            'Add controls
            .Controls.Add(myDGV)        'Data grid
            .Controls.Add(btnDone)      'Done button
    
        End With
        AddHandler myForm.Load, AddressOf myForm_Load '<-- event handler
        myForm.ShowDialog()
    

    And add the the sub for the eventhandler

    Private Sub myForm_Load(sender As Object, e As EventArgs)
    
        For ix As Integer = Application.OpenForms.Count - 1 To 0 Step -1
            Dim frm = Application.OpenForms(ix)
            If frm.Name = "Custom Form 1" Then
                Dim dgv As DataGridView = CType(frm.Controls("MyDgv"), DataGridView)
                dgv.Columns(0).HeaderText = "Mycheckbox"
            End If
        Next
    End Sub
    

    You get as result

    enter image description here

    To get an empty column header you simpoly let the text be empty.

    enter image description here