DataGridView row headings disappear on tabpage2?

Answered DataGridView row headings disappear on tabpage2?

  • Tuesday, February 16, 2010 4:05 AM
     
     
    Public Class Form1


      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'DEMONSTRATES Tabcontrol/datagridview rowheading bug
        Dim tbc As New TabControl

        Dim tbp1 As New TabPage("Tab1")
        Dim dgv1 As New DataGridView
        tbp1.Controls.Add(dgv1)
        dgv1.Dock = DockStyle.Fill

        Dim tbp2 As New TabPage("Tab2")
        Dim dgv2 As New DataGridView
        tbp2.Controls.Add(dgv2)
        dgv2.Dock = DockStyle.Fill

        tbc.TabPages.Add(tbp1)
        tbc.TabPages.Add(tbp2)

        Me.Controls.Add(tbc)
        tbc.Dock = DockStyle.Fill
        LoadDGV(dgv1)
        LoadDGV(dgv2)
        'Why do the row headers show up on the tabpage1 datagridview, but not the tabpage2 datagridview?
      End Sub

      Sub LoadDGV(ByVal dgv As DataGridView)
        Dim dtb As New DataTable
        dtb.Columns.Add("Col1", GetType(String))
        dtb.Columns.Add("Col2", GetType(String))
        dtb.Columns.Add("Col3", GetType(String))
        dtb.Rows.Add("1", "2", "3")
        dtb.Rows.Add("4", "5", "6")
        dtb.Rows.Add("7", "8", "9")
        With dgv
          .DataSource = dtb
          .Rows(0).HeaderCell.Value = "Row0"
          .Rows(1).HeaderCell.Value = "Row1"
          .Rows(2).HeaderCell.Value = "Row2"
          .RowHeadersWidth = 100
        End With
      End Sub
    End Class

    David Streeter

All Replies

  • Tuesday, February 16, 2010 7:29 AM
    Moderator
     
      Has Code

    Hi David,

    Thank you for your valuable feedback.

    The cause of this issue is, the DataGridView is not updated while DataGridView is hidden/invisible. You can check the following similar cases for some instruction  and workarounds.
    http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/b4f5079c-c8f1-4a2d-a476-8cbef1e0debb
    http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/44e13cb2-15e2-4b40-b8ed-9adb80e9b6c7/

    One workaround:
    Use the TabControl's SelectedIndexChanged event - this is called everytime when a TabPage within the TabControl is selected. And create a sub that redraws the DataGridView or try the DataGridView.Invalidate() method.

    Public Sub Tab_Changes(ByVal sender As System.Object, ByVal e As System.EventArgs)
            ' use this sub to track if a tab is selected in the tab control & force a row and column redraw
            Dim tabC As TabControl
            Dim dgvChart As DataGridView
            Dim strTab As String
    
            'cast to TabControl to work with
            If TypeOf sender Is TabControl Then
                tabC = DirectCast(sender, TabControl)
    
                'cast to DGV to work with
                If TypeOf tabC.TabPages(tabC.SelectedIndex).Controls(dgvChart.Name) Is DataGridView Then
                    dgvChart = DirectCast(tabC.TabPages(tabC.SelectedIndex).Controls(DataGridView1.Name), DataGridView)
    
                    'Invalidate the tabpage's dgv
                    dgvChart.Invalidate()
    
                    ' OR call a bespoke sub called Sub_DGVRedraw(Byval dgvInput as DataGridView) that will redraw the headers
                    Sub_DGVRedraw(dgvChart)
    
                End If
            End If
        End Sub
    


    Best regards,

    Martin Xie

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Tuesday, February 16, 2010 7:43 AM
     
     Answered Has Code
    David,

    Probably they would not call it a bug but known behaviour.

    I call this a bug.

            Me.Controls.Add(tbc)
            tbc.Dock = DockStyle.Fill
            LoadDGV(dgv1)
            tbc.SelectTab(1)
            LoadDGV(dgv2)
            'Why do the row headers show up on the tabpage1 datagridview, but not the tabpage2 datagridview?
    The Tabpages have the bad habbit that things are not done when the page is not visible.

    Nevertheless, if I did found it, I would report it on

    Connect.Microsoft.Com

    as a bug

    Success
    Cor
    • Marked As Answer by David Streeter Tuesday, February 16, 2010 10:54 PM
    •  
  • Tuesday, February 16, 2010 10:52 PM
     
      Has Code
    I don't think this is a redraw issue. The .HeaderCell.Value property for the second datagridview is being set to Nothing.

    See following code (adds to msgbox calls to above code):

    Public Class Form1
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'DEMONSTRATES Tabcontrol/datagridview rowheading bug
        Dim tbc As New TabControl
    
        Dim tbp1 As New TabPage("Tab1")
        Dim dgv1 As New DataGridView
        tbp1.Controls.Add(dgv1)
        dgv1.Dock = DockStyle.Fill
    
        Dim tbp2 As New TabPage("Tab2")
        Dim dgv2 As New DataGridView
        tbp2.Controls.Add(dgv2)
        dgv2.Dock = DockStyle.Fill
    
        tbc.TabPages.Add(tbp1)
        tbc.TabPages.Add(tbp2)
    
        Me.Controls.Add(tbc)
        tbc.Dock = DockStyle.Fill
        LoadDGV(dgv1)
        LoadDGV(dgv2)
    
        MsgBox("dgv1.Rows(0).HeaderCell.Value=" & dgv1.Rows(0).HeaderCell.Value.ToString) 'works
        MsgBox("dgv2.Rows(0).HeaderCell.Value=" & dgv2.Rows(0).HeaderCell.Value.ToString) 'throws "object reference not set" error
    
      End Sub
    
      Sub LoadDGV(ByVal dgv As DataGridView)
        Dim dtb As New DataTable
        dtb.Columns.Add("Col1", GetType(String))
        dtb.Columns.Add("Col2", GetType(String))
        dtb.Columns.Add("Col3", GetType(String))
        dtb.Rows.Add("1", "2", "3")
        dtb.Rows.Add("4", "5", "6")
        dtb.Rows.Add("7", "8", "9")
        With dgv
          .DataSource = dtb
          .Rows(0).HeaderCell.Value = "Row0"
          .Rows(1).HeaderCell.Value = "Row1"
          .Rows(2).HeaderCell.Value = "Row2"
          .RowHeadersWidth = 100
        End With
      End Sub
    End Class
    


    David Streeter
  • Tuesday, February 16, 2010 10:54 PM
     
     
    Thanks Cor, that work-around (selecting the second tab before filling it) works, and is simpler than DirectCast.

    David Streeter