Using one datagridview across multiple tabs in tabcontrol

坚强是说给别人听的谎言 提交于 2019-12-22 18:44:16

问题


I have a datagridview (datagridview1) on TabPage1 of TabControl1 which is one my 'Records' form. Currently I populate the datagridview with a loop that executes on the page load event and loads the data in from an excel file that it is an included resource. In the loop I also have tabs created and named for each sheet and sheet name that the excel file has. The two sheets I have in the excel file current are name "2012" and "2013". the first tab in the TabControl is named "2013" and the second tab dynamically created and named "2012" because I start the loop by setting the current year sheet to the first tab and the data in the 2013 sheet is read into the datagridview via my loop. What I need help doing is using the same datagridview on each new tab, but updating it to show the respective year's (sheet) data.

Here's my code for Records Form

Imports System.Data.OleDb
Imports Microsoft.Office.Interop.Excel

Public Class Records

Dim excel_app As Excel.Application
Dim workbook As Excel.Workbook
Dim sheet_name As String
Dim sheet As Excel.Worksheet
Dim ColumnCount, RowCount, TotalCellCount As Long
Dim yearstamp As String = _
    DateTime.Now.ToString("yyyy")
Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
Dim xlPath = IO.Path.Combine(exeDir.DirectoryName, "Records.xlsx")

Sub PopulateDataGridView()
    'Loop through each column
    Dim cIndex As Integer = 0
    Dim rIndex As Integer = 0
    While cIndex < DataGridView1.ColumnCount

        'Loop through and populate each row in column
        rIndex = 0
        While rIndex < DataGridView1.RowCount

            If cIndex = 0 Then
                'Set row header titles
                DataGridView1.Rows.Item(rIndex).HeaderCell.Value = sheet.Range("A1").Offset(rIndex + 1, cIndex).Value()

                DataGridView1.Rows(rIndex).Cells(cIndex).Value = sheet.Range("A1").Offset(rIndex + 1, cIndex + 1).Value()
            End If
            If cIndex > 0 Then
                DataGridView1.Rows(rIndex).Cells(cIndex).Value = sheet.Range("A1").Offset(rIndex + 1, cIndex + 1).Value()
            End If

            'Set column header title
            DataGridView1.Columns(cIndex).HeaderText = sheet.Range("A1").Offset(0, cIndex + 1).Value

            'Change last cell (Result) color Red or Green to represent positive gain or negative loss
            If rIndex = RowCount - 2 Then
                If DataGridView1.Rows(rIndex).Cells(cIndex).Value < 0 Then
                    DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Red
                    DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If DataGridView1.Rows(rIndex).Cells(cIndex).Value > 0 Then
                    DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Green
                    DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If DataGridView1.Rows(rIndex).Cells(cIndex).Value = 0 Then
                    DataGridView1.Rows(rIndex).Cells(cIndex).Value = "Broke Even"
                End If

            End If

            rIndex = rIndex + 1

        End While

        'Make column unsortable
        DataGridView1.Columns(cIndex).SortMode = DataGridViewColumnSortMode.NotSortable


        cIndex = cIndex + 1

    End While
End Sub

Private Sub Records_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ' Get the Excel application object.
    excel_app = New Excel.Application

    ' Make Excel visible (optional).
    excel_app.Visible = False

    ' Open the workbook.
    workbook = excel_app.Workbooks.Open(xlPath)

    sheet_name = yearstamp


    'Adds tabs (if needed) and names each tab after respective excel file sheet
    Dim name As String
    For w As Integer = 1 To workbook.Sheets.Count
        name = workbook.Sheets(w).name
        If Not (TabControl1.TabPages.Count = workbook.Sheets.Count) Then
            TabPage1.Text = sheet_name
            ' Create the new tab page
            Dim tab As New TabPage(name)
            ' Add the tabpage to the existing TabCrontrol
            TabControl1.TabPages.Add(tab)
        End If

    Next w


    sheet = excel_app.Worksheets(sheet_name)

    ColumnCount = sheet.Range("A1").CurrentRegion.Columns.Count
    RowCount = sheet.Range("A1").CurrentRegion.Rows.Count

    DataGridView1.ColumnCount = ColumnCount - 1
    DataGridView1.RowCount = RowCount - 1
    DataGridView1.ColumnHeadersVisible = True
    DataGridView1.RowHeadersVisible = True
    TotalCellCount = DataGridView1.ColumnCount * DataGridView1.RowCount

    DataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing
    DataGridView1.AllowUserToResizeColumns = False
    DataGridView1.AllowUserToResizeRows = False
    DataGridView1.ReadOnly = True

    DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

    'Calls Loop to populate the datagridview
    PopulateDataGridView()

    DataGridView1.AutoResizeColumns()

    'Resize all Row Headers so user can see Row Titles without resizing
    DataGridView1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)

End Sub

Private Sub dataGridView1_CellPainting(ByVal sender As System.Object, ByVal e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    If e.ColumnIndex > -1 And e.RowIndex > -1 Then

        If DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = " $0.00" Then
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.ForeColor = Color.White
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.BackColor = DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.ForeColor
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.SelectionForeColor = SystemColors.Highlight
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.SelectionBackColor = DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.SelectionForeColor
        End If

    End If



End Sub

I'm editing this only to append the solution in case anyone else needs some guidance. The code below allows my datagridview to be carried to whichever tab is active and also updates the datagridview cells to show the data from the corresponding excel sheet's values. I hope this is able to help!

Imports System.Data.OleDb
Imports Microsoft.Office.Interop.Excel

Public Class Records

Dim excel_app As Excel.Application
Dim workbook As Excel.Workbook
Dim sheet_name As String
Dim sheet As Excel.Worksheet
Dim ColumnCount, RowCount, TotalCellCount As Long
Dim yearstamp As String = _
    DateTime.Now.ToString("yyyy")
Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
Dim xlPath = IO.Path.Combine(exeDir.DirectoryName, "Records.xlsx")

Sub PopulateDataGridView()
    'Loop through each column
    Dim cIndex As Integer = 0
    Dim rIndex As Integer = 0
    While cIndex < DataGridView1.ColumnCount

        'Loop through and populate each row in column
        rIndex = 0
        While rIndex < DataGridView1.RowCount

            If cIndex = 0 Then
                'Set row header titles
                DataGridView1.Rows.Item(rIndex).HeaderCell.Value = sheet.Range("A1").Offset(rIndex + 1, cIndex).Value()

                DataGridView1.Rows(rIndex).Cells(cIndex).Value = sheet.Range("A1").Offset(rIndex + 1, cIndex + 1).Value()
            End If
            If cIndex > 0 Then
                DataGridView1.Rows(rIndex).Cells(cIndex).Value = sheet.Range("A1").Offset(rIndex + 1, cIndex + 1).Value()
            End If

            'Set column header title
            DataGridView1.Columns(cIndex).HeaderText = sheet.Range("A1").Offset(0, cIndex + 1).Value

            'Change last cell (Result) color Red or Green to represent positive gain or negative loss
            If rIndex = RowCount - 2 Then
                If DataGridView1.Rows(rIndex).Cells(cIndex).Value < 0 Then
                    DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Red
                    DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If DataGridView1.Rows(rIndex).Cells(cIndex).Value > 0 Then
                    DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Green
                    DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If DataGridView1.Rows(rIndex).Cells(cIndex).Value = 0 Then
                    DataGridView1.Rows(rIndex).Cells(cIndex).Value = "Broke Even"
                End If

            End If

            rIndex = rIndex + 1

        End While

        'Make column unsortable
        DataGridView1.Columns(cIndex).SortMode = DataGridViewColumnSortMode.NotSortable


        cIndex = cIndex + 1

    End While
End Sub

Private Sub Records_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ' Get the Excel application object.
    excel_app = New Excel.Application

    ' Make Excel visible (optional).
    excel_app.Visible = False

    ' Open the workbook.
    workbook = excel_app.Workbooks.Open(xlPath)

    sheet_name = yearstamp


    'Adds tabs (if needed) and names each tab after respective excel file sheet
    Dim name As String
    For w As Integer = 1 To workbook.Sheets.Count
        name = workbook.Sheets(w).name
        If Not (TabControl1.TabPages.Count = workbook.Sheets.Count) Then
            TabPage1.Text = sheet_name
            ' Create the new tab page
            Dim tab As New TabPage(name)
            ' Add the tabpage to the existing TabCrontrol
            TabControl1.TabPages.Add(tab)
        End If

    Next w


    sheet = excel_app.Worksheets(sheet_name)

    ColumnCount = sheet.Range("A1").CurrentRegion.Columns.Count
    RowCount = sheet.Range("A1").CurrentRegion.Rows.Count

    DataGridView1.ColumnCount = ColumnCount - 1
    DataGridView1.RowCount = RowCount - 1
    DataGridView1.ColumnHeadersVisible = True
    DataGridView1.RowHeadersVisible = True
    TotalCellCount = DataGridView1.ColumnCount * DataGridView1.RowCount

    DataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing
    DataGridView1.AllowUserToResizeColumns = False
    DataGridView1.AllowUserToResizeRows = False
    DataGridView1.ReadOnly = True

    DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

    'Calls Loop to populate the datagridview
    PopulateDataGridView()

    DataGridView1.AutoResizeColumns()

    'Resize all Row Headers so user can see Row Titles without resizing
    DataGridView1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)

End Sub

Private Sub dataGridView1_CellPainting(ByVal sender As System.Object, ByVal e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    If e.ColumnIndex > -1 And e.RowIndex > -1 Then

        If DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = " $0.00" Then
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.ForeColor = Color.White
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.BackColor = DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.ForeColor
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.SelectionForeColor = SystemColors.Highlight
            DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.SelectionBackColor = DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.SelectionForeColor
        End If

    End If

End Sub

Private Sub TabControl1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
    Dim tab As TabPage = Me.TabControl1.SelectedTab
    If ((Not tab Is Nothing) AndAlso (Not tab.Controls.Contains(Me.DataGridView1))) Then
        tab.Controls.Add(Me.DataGridView1)
    End If
    sheet_name = TabControl1.SelectedTab.Text
    sheet = excel_app.Worksheets(sheet_name)
    PopulateDataGridView()
End Sub

回答1:


You could just move the DataGridView to the selected TabPage:

Private Sub TabControl1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
    Dim tab As TabPage = Me.TabControl1.SelectedTab
    If ((Not tab Is Nothing) AndAlso (Not tab.Controls.Contains(Me.DataGridView1))) Then
        tab.Controls.Add(Me.DataGridView1)
        If (Me.isDataLoaded) Then
            'TODO: Me.DataGridView1.DataSource = ?
        End If
    End If
End Sub

Private isDataLoaded As Boolean = False 


来源:https://stackoverflow.com/questions/20663578/using-one-datagridview-across-multiple-tabs-in-tabcontrol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!