如何在表单按钮单击上添加进度条以显示form2加载的进度

时间:2013-12-15 19:51:46

标签: vb.net progress-bar backgroundworker

我有一个带有“查看记录”按钮的“开始”表单。在Records Form Load事件中,我有一个循环,用于填充记录表单上的datagridview。我想要做的是在“开始”表单上的“查看记录”按钮旁边显示一个进度条,当用户单击“查看记录”按钮时,该按钮会在“记录”表单上显示datagridview的进度。然后,一旦datagridview循环成功完成,我想调出记录表单(但仍然将开始表单作为父表单打开,因此“查看记录”表单将由ShowDialog启动)。我有简单的代码来显示“查看记录”按钮上的进度条单击。我正在四处寻找可能后台工作者可能是我需要的,但我不知道如何使用它。有人可以帮助我完成它并提供一些代码来帮助我吗?一些信息,开始表单称为“开始”,查看记录表单称为“记录”。进度条名称为“pb”。提前感谢任何试图提供帮助的人!

好的,这是带错误的更新代码

Imports Office = Microsoft.Office.Core
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Start
Dim Records As New Records
Dim excel_app As Excel.Application
Dim workbook As Excel.Workbook
Dim sheet_name As String
Dim sheet As Excel.Worksheet
Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
Dim xlPath = IO.Path.Combine(exeDir.DirectoryName, "Records.xlsx")

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    bw.RunWorkerAsync()

End Sub

Private Sub bw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork



    ' 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 = "2013"

    sheet = excel_app.Worksheets("2013")

    Dim ColumnCount, RowCount, TotalCellCount As Long
    ColumnCount = sheet.Range("A1").CurrentRegion.Columns.Count
    RowCount = sheet.Range("A1").CurrentRegion.Rows.Count

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

    pb.Visible = True
    pb.Minimum = 0
    pb.Value = 0
    pb.Maximum = TotalCellCount

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


    Records.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

    'Loop through each column
    Dim cIndex As Integer = 0
    While cIndex < ColumnCount

        'Loop through and populate each row in column
        Dim rIndex As Integer = 0
        While rIndex < RowCount - 1
            If cIndex = 0 Then
                'Set row header titles
                Records.DataGridView1.Rows.Item(rIndex).HeaderCell.Value = sheet.Range("A1").Offset(rIndex + 1, cIndex).Value()

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

            'Set column header title
            Records.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 Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value < 0 Then
                    Records.DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Red
                    Records.DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value > 0 Then
                    Records.DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Green
                    Records.DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
                End If
                If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = 0 Then
                    Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = "Broke Even"
                End If

            End If

            'Update the progress bar after each cell is populated
            bw.ReportProgress((rIndex * cIndex) / TotalCellCount)

            rIndex = rIndex + 1

        End While

        'Format all cells in column as currency values
        Records.DataGridView1.Columns(cIndex).DefaultCellStyle.Format = "c"
        'Make column unsortable
        Records.DataGridView1.Columns(cIndex).SortMode = DataGridViewColumnSortMode.NotSortable
        'Resize all Row Headers so user can see Row Titles without resizing
        Records.DataGridView1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)

        cIndex = cIndex + 1
    End While

    Records.DataGridView1.AutoResizeColumns()

End Sub

Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
    pb.Value = e.ProgressPercentage
End Sub

Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
    If e.Error IsNot Nothing Then
        MessageBox.Show(e.Error.Message, "Background Worker Exception", MessageBoxButtons.OK, MessageBoxIcon.Error)
    Else
        If e.Cancelled Then
            'worker was cancelled
        Else
            'worker completed, open form2 here
            pb.Visible = False
            Records.ShowDialog()
            If (Records.DialogResult) Then
                ' Close the workbook.
                workbook.Close()

                ' Close the Excel server.
                excel_app.Quit()
            End If

        End If
    End If
End Sub

我这样做了吗?我该如何修复错误?

1 个答案:

答案 0 :(得分:1)

我会在Form1上使用后台工作程序,然后订阅其ProgressChanged事件以更新进度条。然后,当worker完成时,您可以将该数据传递给Form2并将其打开。

假设您将名为bw的BackgroundWorker添加到Form1

在按钮点击事件中,您需要通过调用bw.RunWorkerAsync

来启动工作人员
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
  Setup()
  bw.RunWorkerAsync()

End Sub

Private Sub Setup()
' 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 = "2013"

sheet = excel_app.Worksheets("2013")

Dim ColumnCount, RowCount, TotalCellCount As Long
ColumnCount = sheet.Range("A1").CurrentRegion.Columns.Count
RowCount = sheet.Range("A1").CurrentRegion.Rows.Count

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

pb.Visible = True
pb.Minimum = 0
pb.Value = 0
pb.Maximum = TotalCellCount

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


Records.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

End Sub

然后在bw.DoWork事件中,您将运行代码来获取数据。创建表单级变量,以便您可以在DoWork和RunWorkerCompleted事件中访问它

Dim f as New RecordForm

Private Sub bw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork


'Loop through each column
Dim cIndex As Integer = 0
While cIndex < ColumnCount

    'Loop through and populate each row in column
    Dim rIndex As Integer = 0
    While rIndex < RowCount - 1
        If cIndex = 0 Then
            'Set row header titles
            Records.DataGridView1.Rows.Item(rIndex).HeaderCell.Value = sheet.Range("A1").Offset(rIndex + 1, cIndex).Value()

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

        'Set column header title
        Records.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 Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value < 0 Then
                Records.DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Red
                Records.DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
            End If
            If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value > 0 Then
                Records.DataGridView1.Item(cIndex, rIndex).Style.BackColor = Color.Green
                Records.DataGridView1.Item(cIndex, rIndex).Style.ForeColor = Color.White
            End If
            If Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = 0 Then
                Records.DataGridView1.Rows(rIndex).Cells(cIndex).Value = "Broke Even"
            End If

        End If

        'Update the progress bar after each cell is populated
        bw.ReportProgress((rIndex * cIndex) / TotalCellCount)

        rIndex = rIndex + 1

    End While

    'Format all cells in column as currency values
    Records.DataGridView1.Columns(cIndex).DefaultCellStyle.Format = "c"
    'Make column unsortable
    Records.DataGridView1.Columns(cIndex).SortMode = DataGridViewColumnSortMode.NotSortable
    'Resize all Row Headers so user can see Row Titles without resizing
    Records.DataGridView1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)

    cIndex = cIndex + 1
End While

Records.DataGridView1.AutoResizeColumns()
End Sub

Private Sub bw_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
  ProgressBar.Value = e.ProgressPercentage
End Sub

当工人完成时,它将触发已完成的事件。

Private Sub bw_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
  If e.Error IsNot Nothing Then
    MessageBox.Show(e.Error.Message, "Background Worker Exception", MessageBoxButtons.OK, MessageBoxIcon.Error)
  Else
    If e.Cancelled Then
      'worker was cancelled
    Else
      'worker finished. open Form2
      f.Show
    End If
  End If
End Sub