Vb.net 从BackgroundWorker填充DataGridView
情况就是这样:Vb.net 从BackgroundWorker填充DataGridView,vb.net,winforms,visual-studio-2012,datagridview,backgroundworker,Vb.net,Winforms,Visual Studio 2012,Datagridview,Backgroundworker,情况就是这样: 我在表单中有一个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.
我在表单中有一个
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给我举了一个我该怎么做的例子之后,我这样做了,但现在我遇到了一个问题,当我放置制动点时,它甚至没有进入
bw\u 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
的影响
如果您需要任何更多的信息或代码部分,请随时告诉我,这样我就可以解决这个问题
谢谢,Hoh您应该使用事件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
无需在ProgressChanged事件中使用InvokeRequired 在回顾了这篇文章的一些细节之后,我可以指出一些我看到的东西
ProgressChanged事件中设置源代码,如果您有一个委托并正确使用它,则无需这样做
进度更改事件
仅用于报告进度,而不用于更改UI或任何控件FirstSub
方法,我可能会从加载事件或单击事件中假设,这无论如何都不重要。下面是我所做的改变,应该对你有好处。你也可以看看我的另一个答案,这两个答案都是很好的参考,看看需要发生什么
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您能在VB.net中为我提供一个代码吗?我对C不太熟悉。谢谢。我在问题中添加了我的新代码,现在我有了一个新问题,所以我甚至不能说这是否有效。”在Carlos给我举了一个我应该做什么的例子后,我这样做了,但现在我有一个问题,当我放置BrakePoint时,它甚至没有进入bw_DoWork sub“Hello MrCodexer,我很高兴在完全按照你说的做了之后收到这个消息。这个项目太大了吗?我可以看一下吗?另外,你的代码是:DataBaseLayer.FillDTwithSP(“ArticlesSelect”,ds_Tables.Articles)可能就是你出错的地方,你有没有设置断点?如果有错误,把代码移到AddSource中。。。我在我的帖子中解释了这一点…嗯,还有一个问题(重命名DGV标题)。但是,看起来那个表单正在显示,thanBW开始工作,than表单被冻结,直到DGV被填充(它甚至没有被禁用),它全部被启用(但不可写入(文本框))