Results 1 to 5 of 5

Thread: [RESOLVED] Manually adjusting column width in DataGridView requires two iterations

  1. #1

    Thread Starter
    Member
    Join Date
    Mar 2022
    Posts
    39

    Resolved [RESOLVED] Manually adjusting column width in DataGridView requires two iterations

    I am using a DataGridView (dgv) which resides on a tab page in a tab control, and there are no problems connecting to a dt via .datasource = dt and populating the dgv with column names (headers) as well as all cell data. The goal is to add row numbers in the row header for each row. I learned that if I first set dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders, the column width of all columns including the row header width look fine, but the update is VERY SLOW. Therefore, if I first disable resizing, then add the row headers via looping, and then manually set the row header width, the results look fine but only after using the code below twice. After the first sweep through the code, the original column header widths are off, and there is no blank cell in the upper left. After the second sweep through the code, everything looks fine -- with all columns header widths correct with an empty cell in the upper left corner.

    The question is, how can I prevent the need to sweep through the code the second time, so that all column header widths are correct, and the cell in the upper left corner is empty?


    Code:
                Dim dgv As DataGridView = CType(TabControl2.TabPages(1).Controls("dgv1"), DataGridView)
                If dgv IsNot Nothing Then
                    dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing 
                    dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing 
                    If dgv.Rows.Count - 1 <> DataNumRows Then Exit Sub
                    If dgv.Columns.Count = 0 Then Exit Sub
                    Dim cnt As Integer = 0
                    For Each row As DataGridViewRow In dgv.Rows
                        If cnt > dgv.Rows.Count - 2 Then Exit For
                        dgv.Rows(cnt).HeaderCell.Value = (cnt + 1).ToString
                        cnt += 1
                    Next
                    dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
                    dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing
                    'dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders   'This causes long delay when set to True
                    dgv.EnableHeadersVisualStyles = True
                    dgv.ColumnHeadersDefaultCellStyle.ForeColor = Color.Black
                    dgv.RowHeadersDefaultCellStyle.ForeColor = Color.Black
                    dgv.RowHeadersVisible = True
                    dgv.RowHeadersWidth = Len(cnt.ToString) * 20   'Manually setting rowheader width is much faster
                    dgv.Refresh()
                End If
    Last edited by pel11; Aug 9th, 2022 at 11:26 AM.

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

    Re: Manually adjusting column width in DataGridView requires two iterations

    Try wrapping your loading code with Dgv.SuspendLayout() and dgv.ResumeLayout()

  3. #3

    Thread Starter
    Member
    Join Date
    Mar 2022
    Posts
    39

    Re: Manually adjusting column width in DataGridView requires two iterations

    Thanks, I saw that in some forums. Will try and get back if resolved.

  4. #4

    Thread Starter
    Member
    Join Date
    Mar 2022
    Posts
    39

    Re: Manually adjusting column width in DataGridView requires two iterations

    Didn't help thus far.

  5. #5

    Thread Starter
    Member
    Join Date
    Mar 2022
    Posts
    39

    Resolved Re: Manually adjusting column width in DataGridView requires two iterations

    I was able to get very good row header labels in the dgv by doing the following:

    Step 1:

    Code:
     dgv.Datasource = dt ' connect to the datatable - loads the data into the dgv
      'specify that you want centered column headers
      Dim dgv1ColumnHeaderStyle As New DataGridViewCellStyle()
      dgv1ColumnHeaderStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
      dgv.ColumnHeadersDefaultCellStyle = dgv1ColumnHeaderStyle
      'Point the dgv to a method called DGVdatachanged, which the dgv will run *after* it's loaded and viewable"
      AddHandler dgv1.DataBindingComplete, AddressOf main.DGVdatachanged 'Careful -- you should only use Addhandler here *the first* time dgv is connected to dt.  Otherwise, on the first call to DGVchanged, the handler will be removed.
    Step 2:

    'Create the following handler for the DGV to add the row headers:

    Code:
    Sub DGVdatachanged(ByVal SENDER As Object, ByVal E As EventArgs)
            If TypeOf SENDER Is DataGridView Then
                Dim dgv As DataGridView = CType(SENDER, DataGridView) 'CType(TabControl2.TabPages(1).Controls("dgv1"), DataGridView)
                If dgv.Rows.Count - 1 <> NumRecords Then Exit Sub
                If dgv.Columns.Count = 0 Then Exit Sub
                Dim cnt As Integer = 0
                For Each row As DataGridViewRow In dgv.Rows
                    If cnt > dgv.Rows.Count - 2 Then Exit For
                    dgv.Rows(cnt).HeaderCell.Value = (cnt + 1).ToString
                    cnt += 1
                Next
                Dim dgvColumnHeaderStyle As New DataGridViewCellStyle()
                dgvColumnHeaderStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
                dgv.ColumnHeadersDefaultCellStyle = dgvColumnHeaderStyle
                dgv.EnableHeadersVisualStyles = True
                dgv.ColumnHeadersDefaultCellStyle.ForeColor = Color.Black
                dgv.RowHeadersDefaultCellStyle.ForeColor = Color.Black
                dgv.RowHeadersVisible = True
                dgv.RowHeadersWidth = Len(cnt.ToString) * 20
                dgv.Columns(0).Width = dgv.RowHeadersWidth
                dgv.Refresh()
                RemoveHandler dgv.DataBindingComplete, AddressOf DGV1datachanged
            End If
        End Sub
    Step 3:

    Any time you modify the DGV's data, i.e., using another dgv.Datasource = dt, you need to manually call the method that adds row headers again, since .NET (Vb.net, C#) will drop the row headers any time a dgv is updated with data. So say, for example, you just updated dgv with dt3; you will need to do the following to get row headers again in dgv:

    Code:
    dgv.DataSource = dt3
    Dim e As EventArgs
    DGVdatachanged(dgv, e)
    Note: very important, the RemoveHandler needs to be at the end of the DGVdatachanged method, because if it's absent and you left the handler intact, then every cell that gets updated in dgv will call DGVdatachanged, and the code will hang. I only used the Addhandler once, when I first loaded the dgv with data. But on later updates, just manually call DGVdatachanged.
    Last edited by pel11; Aug 9th, 2022 at 11:40 AM.

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