情况如此:
我的表单中有DataGridView
,当我开始填写表单DGV
时,应该开始填写BackgroundWorker
。
Private Sub FirstSub()
adoconn()
Me.Enabled = False
bw.RunWorkerAsync()
Me.Enabled = True
End Sub
Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bw.DoWork
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
If DataGridView1.InvokeRequired Then
'//For VB 10 you can use an anonymous sub
DataGridView1.Invoke(Sub() bw_DoWork(sender, e))
Else
Try
DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles)
Me.DataGridView1.DataSource = ds_Tables.Articles
Me.DataGridView1.ClearSelection()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End If
End Sub
在Carlos给我一个我应该做什么的例子后,我做了这个,但现在我有一个问题,当我放置BrakePoint时甚至没有进入bw_DoWork
sub
Private Sub FirstSub()
adoconn()
Me.Enabled = False
bw.WorkerReportsProgress = True
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
Me.Enabled = True
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
Try
DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles)
Me.DataGridView1.DataSource = ds_Tables.Articles
Me.DataGridView1.ClearSelection()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
bw.ReportProgress(sender, e)
End Sub
所以,我想要的是禁用表单上的所有控件,直到我的DataTable
被填充并且DataGridView
显示DT
的结果集。
问题是,当我加载此表单时,它会在完成所有操作后再次冻结和取消冻结,因此根本不会产生BackgroundWorker
的影响。
如果您需要更多信息或代码部分,请随时告诉我,以便我可以解决此问题。
谢谢,
呼和
答案 0 :(得分:2)
在回顾了这个主题的一些细节之后,我可以指出一些我看到的内容。
ProgressChanged Event
中设置来源,如果您有代表并且正确使用它,则无需使用。Progress Changed Event
只应用于报告进度,而不是更改用户界面或任何控件。我不确定您的调用FirstSub
方法在哪里,我会假设从加载事件或点击事件中,这无论如何都不重要。以下是我所做的更改,应该对您有益。您还可以查看我的其他答案here和here,两者都非常适合您参考并了解需要进行的操作。
Delegate Sub SetDataTable(ByVal dt As DataTable) 'Your delegate..
Private Sub FirstSub()
adoconn()
Me.Enabled = False
bw.RunWorkerAsync()
Me.Enabled = True
End Sub
'The method that fills DataGridView1
Private Sub AddSource(ByVal dt As DataTable)
If Me.DataGridView1.InvokeRequired Then 'Invoke if required...
Dim d As New SetDataTable(AddressOf AddSource)
Me.Invoke(d, New Object() {dt})
Else 'Otherwise, no invoke required...
Me.DataGridView1.DataSource = dt
Me.DataGridView1.ClearSelection()
End If
End Sub
Private Sub bw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
If Not (bw.CancellationPending) Then
DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles)
AddSource(ds_Tables.Articles)
ElseIf (bw.CancellationPending) Then
e.Cancel = True
End If
End Sub
请告诉我这是如何为您解决的,并查看我给您的其他两个链接。另请注意,您可以将DoWork
中的调用更改为方法AddSource,以便不通过DataTable
并调用它...
MrCodexer
答案 1 :(得分:0)
您应该使用Event ProgressChanged来执行UI线程中的代码,以便您可以安全地更新控件:
_backgroundWorker.ProgressChanged += New ProgressChangedEventHandler(backgroundWorker_ProgressChanged)
在Do_Work内部,调用这样的进度:
//param is the value you need to update your controls
_backgroundWorker.ReportProgress(p, param)
Private Sub backgroundWorker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
' Update the UI here
End Sub
无需使用InvokeRequired insode ProgressChanged事件。