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被填充(它甚至没有被禁用),它全部被启用(但不可写入(文本框))