使用来自另一个类的backgroundworker更新来自mainform类的标签 [英] Update label from mainform class with backgroundworker from another class

查看:106
本文介绍了使用来自另一个类的backgroundworker更新来自mainform类的标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两节课.

Public Class MainForm

     Private Project As clsProject


Private Sub btnDo_Click
   ...
   Backgroundworker.RunWorkerAsync()

End Sub
 Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork


    Project = New clsProject


End Sub

和MainForm中的两个方法

 Public Shared Sub setLabelTxt(ByVal text As String, ByVal lbl As Label)
    If lbl.InvokeRequired Then
        lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl)
    Else
        lbl.Text = text
    End If
End Sub
Public Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label)
end class

我想从clsProject构造函数更新MainForm的标签.

 MainForm.setLabelTxt("Getting prsadasdasdasdasdry..", MainForm.lblProgress)

,但不会更新它们. 我在做什么错了?

解决方案

您不能直接从BackgroundWorker对GUI元素执行任何操作.一种克服"的方法是通过Me.Invoke强制从主线程执行给定的动作;但这不是理想的过程.此外,您的代码混合了主要形式和外部类(+共享/非共享对象),这使整个结构不太牢固.

确保工作的解决方案依赖于特定的BGW方法来处理GUI元素;例如:ProgressChanged Event.示例代码:

Public Class MainForm
    Private Project As clsProject
    Public Shared bgw As System.ComponentModel.BackgroundWorker

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        bgw = BackgroundWorker1 'Required as far as you want to called it from a Shared method

        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Project = New clsProject
    End Sub

    Public Shared Sub setLabelTxt(ByVal text As String)
        bgw.ReportProgress(0, text) 'You can write any int as first argument as far as will not be used anyway
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Me.Label1.Text = e.UserState 'You can access the given GUI-element directly
        Me.Label1.Update()
    End Sub
End Class

Public Class clsProject
    Public Sub New()
        MainForm.setLabelTxt("Getting prsadasdasdasdasdry..")
    End Sub
End Class

I have two classes.

Public Class MainForm

     Private Project As clsProject


Private Sub btnDo_Click
   ...
   Backgroundworker.RunWorkerAsync()

End Sub
 Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork


    Project = New clsProject


End Sub

and two methods inside MainForm

 Public Shared Sub setLabelTxt(ByVal text As String, ByVal lbl As Label)
    If lbl.InvokeRequired Then
        lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl)
    Else
        lbl.Text = text
    End If
End Sub
Public Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label)
end class

I want to update the labels of MainForm from the clsProject constructor.

 MainForm.setLabelTxt("Getting prsadasdasdasdasdry..", MainForm.lblProgress)

but it does not update them. What am I doing wrong?

解决方案

You cannot execute any action on GUI-elements from the BackgroundWorker directly. One way to "overcome" that is by forcing the given actions to be performed from the main thread via Me.Invoke; but this is not the ideal proceeding. Additionally, your code mixes up main form and external class (+ shared/non-shared objects) what makes the whole structure not too solid.

A for-sure working solution is relying on the specific BGW methods for dealing with GUI elements; for example: ProgressChanged Event. Sample code:

Public Class MainForm
    Private Project As clsProject
    Public Shared bgw As System.ComponentModel.BackgroundWorker

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        bgw = BackgroundWorker1 'Required as far as you want to called it from a Shared method

        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Project = New clsProject
    End Sub

    Public Shared Sub setLabelTxt(ByVal text As String)
        bgw.ReportProgress(0, text) 'You can write any int as first argument as far as will not be used anyway
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Me.Label1.Text = e.UserState 'You can access the given GUI-element directly
        Me.Label1.Update()
    End Sub
End Class

Public Class clsProject
    Public Sub New()
        MainForm.setLabelTxt("Getting prsadasdasdasdasdry..")
    End Sub
End Class

这篇关于使用来自另一个类的backgroundworker更新来自mainform类的标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆