【问题标题】:Filling DataGridView from BackgroundWorker从 BackgroundWorker 填充 DataGridView
【发布时间】:2014-09-17 05:15:45
【问题描述】:

是这样的:
我有一个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 的影响。

如果您需要更多信息或代码部分,请随时告诉我,以便我解决此问题。

谢谢,
呵呵

【问题讨论】:

    标签: vb.net winforms visual-studio-2012 datagridview backgroundworker


    【解决方案1】:

    您应该使用在 UI 线程中执行代码的 Event ProgressChanged,这样您就可以安全地更新您的控件:

    _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。

    【讨论】:

    • 你能给我一个VB.net的代码吗?我对 C# 不是很熟悉。谢谢。
    • 我将我的新代码添加到问题中,现在我有一个新问题,所以甚至不能说这是否有效。
    • "在 Carlos 给我一个应该怎么做的例子之后,我做了这个,但是现在我有一个问题,当我放置 BrakePoint 时甚至没有进入 bw_DoWork sub"
    【解决方案2】:

    在查看了该线程的一些细节之后,我可以指出一些我看到的东西。

    1. 您正在尝试将源设置为ProgressChanged Event,如果您有委托并正确使用它,则不需要。
    2. Progress Changed Event 只能用于报告进度,不能更改 UI 或任何控件。
    3. 无需添加处理程序,因为它们已经得到处理。

    我不确定您在哪里调用 FirstSub 方法,我可能会从加载事件或单击事件中假设,这并不重要。以下是我所做的更改,应该对您有好处。您还可以查看我的其他答案 herehere,两者都非常适合您参考并了解需要做什么。

     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

    【讨论】:

    • 您好,MrCodexer,很幸运,在完全按照您所说的操作后,我收到了这条消息。 imgur.com/XQweeyu
    • 这个项目是不是太大了,所以我可以看看它?
    • 另外,您的代码:DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles) 可能是您出错的地方,您是否设置了断点?
    • 如果您的错误存在将该代码移出并放入 AddSource... 我在帖子中对此进行了解释...
    • 嗯,还有其他问题(重命名 DGV 标头)。但是,似乎该表单正在显示,比 BW 开始工作并且比表单被冻结直到 DGV 被填充(它甚至没有被禁用),它都已启用(但无法写入(文本框)。)
    猜你喜欢
    • 2019-11-02
    • 1970-01-01
    • 2011-03-08
    • 2013-08-11
    • 2012-03-14
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    相关资源
    最近更新 更多