Code to show a DataGridView works only if I run an

2019-09-15 14:24发布

I wrote a code to show/hide content of a certain DataTable into a DataGridView.

DataGridView appears and disappears when I click a button. I don't get errors but nothing is shown.

But if I click another button (who shows another form) and then go back to the main form, the code works. (??!!??)

I wasn't able to understand what (in the 2nd code) makes the first code to work: it seems there aren't connections between two codes.

EDIT
I made some tests and I can add more informations:
I added a button to show (in a msgbox) the DataGridView properties. The control was correctly added and all properties are correct. The property "Visible" is set "True" but the DataGridView is still "invisible".

I added a button that sets DGV_Tbl.Visible = False and DGV_Tbl.Visible = True And when I click it the DataGridView appears.

But if I click Btn_ShowHideTbl again (to remove DGV) and again (to re-add DGV) DataGridView is still "invisible".

This doesn't happens when I click the button to open the second form and then I close it to go back to the first form.
In this case all works correctly.

I could solve adding DGV_Tbl.Visible = False and DGV_Tbl.Visible = True to the first code but I don't think it's a good idea.
I would like to understand the problem and solve it without "strange instructions".

EDIT 2
I noticed that also the code .AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells) doesn't work without opening the 2nd form.
On this istruction DGV_Tbl.Visible = False and DGV_Tbl.Visible = True haven't effect.

EDIT 3
I've done as in the accepted answer, but I posted another question here hoping to understand what's wrong in my code.

This is my code to show/hide DataGridView:

Private Sub Btn_ShowHideTbl_Click(sender As Object, e As EventArgs) Handles Btn_ShowHideTbl.Click
    ShowHideTbl()
End Sub

Private Sub ShowHideTbl()
    'Look for DGV
    Dim DGV_Tbl As DataGridView = Nothing
    Try
        DGV_Tbl = CType(Me.Controls("DGV_Tbl"), DataGridView)
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
    Try
       'If not found I need to show data
       If DGV_Tbl Is Nothing Then
            If Me.CBox_ProcType.Text = "Select a Procedure" Then
                MsgBox("You need To select a Procedure", vbInformation, "Unable to show table")
                Exit Sub
            End If
            DGV_Tbl = New DataGridView
            'It needs to copy data to another DataTable to show Double as Currency
            Using DTemp As DataTable = New DataTable
                Dim TblName As String = Me.CBox_ProcType.Text
                For C As Integer = 0 To DS_All.Tables(TblName).Columns.Count - 1
                    DTemp.Columns.Add(DS_All.Tables(TblName).Columns(C).ColumnName, Type.GetType("System.String"))
                Next
                Dim Arr(DS_All.Tables(TblName).Columns.Count - 1) As String
                For R As Integer = 0 To DS_All.Tables(TblName).Rows.Count - 1
                    For C As Integer = 0 To DS_All.Tables(TblName).Columns.Count - 1
                        If C = 0 Then
                            Arr(C) = DS_All.Tables(TblName).Rows(R)(C).ToString
                        Else
                            Arr(C) = FormatCurrency(DS_All.Tables(TblName).Rows(R)(C).ToString, 2)
                        End If
                    Next
                    DTemp.Rows.Add(Arr)
                Next
                'Working on created DataGridView
                With DGV_Tbl
                    .Name = "DGV_Tbl"
                    'Add control to the Form
                    Me.Controls.Add(DGV_Tbl)
                    .DataSource = DTemp
                    .AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
                    .RowHeadersVisible = False
                    .AllowUserToAddRows = False
                    .AllowUserToDeleteRows = False
                End With
            'Dispose the copied DataTable
            End Using
            'Resizing Form to include new DataGridView
            Dim DGV_H As Integer = 0
            Dim DGV_W As Integer = 0
            For Each R As DataGridViewRow In DGV_Tbl.Rows
                DGV_H += R.Height
            Next
            DGV_H += DGV_Tbl.ColumnHeadersHeight
            'Add more space to include spaces between cells
            DGV_H += CInt(DGV_Tbl.Rows.Count * 0.45)
            For Each C As DataGridViewColumn In DGV_Tbl.Columns
                DGV_W += C.Width
            Next
            'Add more space to include spaces between cells
            DGV_W += CInt(DGV_Tbl.Columns.Count * 0.45)
            DGV_Tbl.Height = DGV_H
            DGV_Tbl.Width = DGV_W
            'Resize the Form
            Me.Height += DGV_H + 30
            Me.Controls("DGV_Tbl").Location = New Point(15, Me.Height - DGV_H - 30)
            'Align for currency
            For x As Integer = 1 To DGV_Tbl.Columns.Count - 1
                DGV_Tbl.Columns(x).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            Next
        Else
            'If DGV exists I need to remove it and resize the form
            Dim DGV_H As Integer = DGV_Tbl.Height
            DGV_Tbl.Dispose()
            Me.Height -= (DGV_H + 30)
        End If
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

This is the code in the button who shows another form (and the code to close the form and go back):

Private Sub Btn_ShowSummary_Click(sender As Object, e As EventArgs) Handles Btn_ShowSummary.Click
    Try
        If Me.CBox_ProcType.Text = "Select a Procedure" OrElse Me.CBox_ProcValue.Text = "Select a Value" Then
            MsgBox("It needs to select a Procedure and a Value",
                   vbInformation, "Unable to show table")
            Exit Sub
        End If

        Summary = "...Here Some text..." & vbCrLf & Split(Me.CBox_ProcType.Text, ".")(1).Trim & vbCrLf & vbCrLf
        Summary &= "...Here Some text..." & Me.CBox_ProcValue.Text & vbCrLf & vbCrLf
        Dim C1Wdt% = -50 
        Dim C2Wdt% = TBox_TotAll.Text.Length 
        For R As Integer = 1 To 4
            Dim CBox_Phase As CheckBox = CType(Me.TLP_Phases.Controls("CBox_Phase" & R.ToString), CheckBox)
            Dim TBox_ValPh As TextBox = CType(Me.TLP_Phases.Controls("TBox_ValPh" & R.ToString), TextBox)
            If CBox_Phase.Checked Then
                Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
                                         CBox_Phase.Text, TBox_ValPh.Text) & vbCrLf
                Dim TBox_SelVarPh As TextBox = CType(Me.TLP_Phases.Controls("TBox_SelVarPh" & R.ToString), TextBox)
                If TBox_SelVarPh.Text = "" OrElse TBox_SelVarPh.Text = "€ 0,00" Then
                    Summary &= "...Here Some text..." & vbCrLf
                Else
                    Dim SelVarTxt$ = If(Val(TBox_SelVarPh.Text) > 0,
                        "...Here Some text..." & TBox_SelVarPh.Text,
                        "...Here Some text..." & TBox_SelVarPh.Text.Substring(1)) & vbCrLf
                    Summary &= SelVarTxt
                End If
            End If
        Next
        Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}", "", New String(CChar("_"), C2Wdt)) & vbCrLf
        Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
                                 "...Here Some text...",
                                 Me.TBox_TotPhases.Text) & vbCrLf
        If Me.TBox_PrtAdg.Text <> "€ 0,00" Then
            Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
                                 "...Here Some text...",
                                 Me.TBox_PrtAdg.Text) & vbCrLf
            Summary &= "...Here Some text..." & TBox_PrtRapp.Text & "...Here Some text..." & TBox_CPrt.Text & "...Here Some text..." & vbCrLf
        End If
        Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
                                 "...Here Some text..." & TBox_ForfPercent.Text,
                                 Me.TBox_ForfImp.Text) & vbCrLf
        Summary &= "...Here Some text..." & TBox_TotPhases.Text & ")" & vbCrLf
        Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}", "", New String(CChar("_"), C2Wdt)) & vbCrLf
        Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
                                 "...Here Some text...",
                                 Me.TBox_TotAll.Text) & vbCrLf
        Me.Hide()
        Me.ShowInTaskbar = False
        Frm_Summary.Show()
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

Here the code of the back button:

Private Sub Btn_CloseNBack_Click(sender As Object, e As EventArgs) Handles Btn_CloseNBack.Click
    Frm_Base.ShowInTaskbar = True
    Frm_Base.Show()
    Me.Close()
End Sub

I don't see any connetion between the codes (but it seems I'm wrong) please show me what I'm missing.

1条回答
Juvenile、少年°
2楼-- · 2019-09-15 14:57

May I suggest another approach for your problem ? If i were you, i would think about using a drawn datagridview, put datatable content into it before hand. Then in the show/hide button, just switch the visibility of that datagridview along with recalculating the form size.

As for the currency column, instead of making another table, you can just populate the datatable into your datagridview, then set the format of that column into currency:

DGV_Tbl.Columns("CurrencyColumn").DefaultCellStyle.Format = "c"

More information about datagridview column formatting can be found here

查看更多
登录 后发表回答