VB.net 后台工作人员 UI
VB.net BackgroundWorker UI
我正在尝试创建一个可根据用户输入生成 excel 文档的应用程序。该文档可能会变得非常广泛(多张),所以我想将文档的创建放在 BackgroundWorker 上并将进度传递给 ProgressBar。
我在创建文档时访问 UI 控件时遇到问题。
如何从 BackgroundWorker 访问多个 UI 控件?
这是我想在 BackgroundWorker 中做的许多事情中的两个非常基本的例子:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
OpenWorkbook()
Dim Combobox() As ComboBox = {ComboBox1, ComboBox2, ComboBox3, ComboBox4}
With xlWorkBook.Sheets("Cover1")
.Range("E5").Value = TextBox1.Text
.Range("E6").Value = TextBox2.Text
.Range("E7").Value = TextBox3.Text
.Range("E8").Value = TextBox4.Text
For i = 0 To Combobox.Count - 1
.Range("A" & i + 1).Value = Combobox(i).Text
Next
End With
CloseWorkBook()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
我完全没有经验,在研究了这个主题之后,我仍然无法与 Delegate/Invoke 相处。任何帮助都是极好的。提前致谢。
正如 Heinzi 所指出的,您不能只将对控件的引用传递到 bgw 中。相反,您传递值。
Option Strict On
Public Class FormControls
WithEvents Bgw As New ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True}
Public Class BgwArgs
Public TxtBx1Txt As String = FormControls.TextBox1.Text
Public TxtBx2Txt As String = FormControls.TextBox2.Text
Public CmbBx1Txt As String = FormControls.ComboBox1.SelectedText
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim BgwArgs As New BgwArgs
Bgw.RunWorkerAsync(BgwArgs)
End Sub
Private Sub Bgw_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles Bgw.DoWork
Dim BgwArgs As BgwArgs = DirectCast(e.Argument, BgwArgs)
.Range("E5").Value = BgwArgs.TxtBx1Txt 'etc
End Sub
End Class
我假设 OpenWorkbook
是一个使用互操作来创建 xlWorkBook
的子程序,而您也想在线程内执行此操作,与 CloseWorkbook
一样,所有这些都应该是在 DoWork 事件中处理,而不是在它们自己的单独例程中处理。
我正在尝试创建一个可根据用户输入生成 excel 文档的应用程序。该文档可能会变得非常广泛(多张),所以我想将文档的创建放在 BackgroundWorker 上并将进度传递给 ProgressBar。
我在创建文档时访问 UI 控件时遇到问题。 如何从 BackgroundWorker 访问多个 UI 控件?
这是我想在 BackgroundWorker 中做的许多事情中的两个非常基本的例子:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
OpenWorkbook()
Dim Combobox() As ComboBox = {ComboBox1, ComboBox2, ComboBox3, ComboBox4}
With xlWorkBook.Sheets("Cover1")
.Range("E5").Value = TextBox1.Text
.Range("E6").Value = TextBox2.Text
.Range("E7").Value = TextBox3.Text
.Range("E8").Value = TextBox4.Text
For i = 0 To Combobox.Count - 1
.Range("A" & i + 1).Value = Combobox(i).Text
Next
End With
CloseWorkBook()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
我完全没有经验,在研究了这个主题之后,我仍然无法与 Delegate/Invoke 相处。任何帮助都是极好的。提前致谢。
正如 Heinzi 所指出的,您不能只将对控件的引用传递到 bgw 中。相反,您传递值。
Option Strict On
Public Class FormControls
WithEvents Bgw As New ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True}
Public Class BgwArgs
Public TxtBx1Txt As String = FormControls.TextBox1.Text
Public TxtBx2Txt As String = FormControls.TextBox2.Text
Public CmbBx1Txt As String = FormControls.ComboBox1.SelectedText
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim BgwArgs As New BgwArgs
Bgw.RunWorkerAsync(BgwArgs)
End Sub
Private Sub Bgw_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles Bgw.DoWork
Dim BgwArgs As BgwArgs = DirectCast(e.Argument, BgwArgs)
.Range("E5").Value = BgwArgs.TxtBx1Txt 'etc
End Sub
End Class
我假设 OpenWorkbook
是一个使用互操作来创建 xlWorkBook
的子程序,而您也想在线程内执行此操作,与 CloseWorkbook
一样,所有这些都应该是在 DoWork 事件中处理,而不是在它们自己的单独例程中处理。