【问题标题】:Pass information from referenced class back to calling form将信息从引用的类传回调用表单
【发布时间】:2014-11-13 14:18:40
【问题描述】:

我们有一个 Windows 窗体应用程序实例化一个 dll,并在该 dll 中实例化类。

编辑:

所以流程是这样的:

FORM > alpsClient (DLL) > 类

我想从班级更新 FORM 上的 backgroundWorker_ProgressChanged 事件。

结束编辑

在类对象中完成可能需要很长时间的工作。

我想将某种类型的进度从课堂传回给调用表单。

我想我需要使用事件。

但是我应该如何引用在后台工作人员中启动进程的表单。

下面是实例化 dll 对象的代码:

   Private Sub alpsManual_bgw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles alpsManual_bgw.DoWork
    Try

        Dim arg As String = CStr(e.Argument)
        objDoc = New alpsClient

        '* Set variables and start
        ' CUT ...

        If fromArchive Then
            '********************************************
            '* Manual Settings                          *
            '********************************************
             ' SET PROPERTIES
             ... CUT for brevity
            '********************************************
        End If

        objDoc.docMap()
        '* Wait until isComplete before starting next
        Do
            System.Threading.Thread.Sleep(1000)
        Loop Until objDoc.isComplete

    Catch ex As Exception

下面是实例化alpsClient.docMap中的类的代码:

Dim objControl As Object = Nothing

Select Case docRef
    Case "YL0PF"                    'Arrears Advice
        objControl = New YL0PF
    Case "YL2PF"                    'Arrears with Additional Interest
        objControl = New YL2PF

... etc

然后:

objControl.dbConn = masterDB
objControl.docRef = docRef
objControl.table2Format = table2Format
objControl.newAddressFormat = newAddressFormat
objControl.dteinp = runDate
' Start
docMap = ""
If Not objControl.Controller() Then docMap = "Errors"

objControl 引用的类中,我想将进度消息发送回调用表单...可能使用事件。

或者这是一个非常糟糕的主意?

【问题讨论】:

  • 为什么这个标签是 C#?
  • 听起来很合理。唯一需要注意的是,如果事件是由在后台线程上运行的代码引发的,则处理该事件的代码也将在后台线程上。如果这试图更新 GUI 将会崩溃:只能在 GUI 线程上更新 GUI。通过在后台线程中对 GUI 对象使用 .Invoke 方法或使用 SynchronizationContext 对象,这相对容易。
  • 所以我需要注册一个事件,然后引发该事件或调用后台工作者'ProgressChanged'事件?

标签: .net vb.net events


【解决方案1】:

您可以确保您的所有控件类都继承自一个公共基类,例如:

Public MustInherit Class ControlBase
   Protected Sub New()
   End Sub

   Public Event ProgressEvent As EventHandler<Of ProgressEventArgs>

   Protected Sub RaiseProgressEvent(current As Integer, maximum as Integer)
       RaiseEvent ProgressEvent(Me, New ProgressEventArgs(current, maximum)
   End Sub

End Class

Public Class ProgressEventArgs : Inherits EventArgs
   Private _current as Integer
   Private _maximum as Integer

   Public Sub New(current As Integer, maximum as Integer)
      _current = current
      _maximum = maximum
   End Sub

   Public ReadOnly Property Current() As Integer
      Get
         Return _current
      End Get
   End Property

   Public ReadOnly Property Maximum() As Integer
      Get
         Return _maximum
      End Get
   End Property
End Class

然后你的每个 YL0PF、YL2PF 等类都继承自这个类并调用 RaiseProgressEvent。

当您实例化课程时,请执行以下操作...

Dim objControl As ControlBase = Nothing

Select Case docRef
    Case "YL0PF"                    'Arrears Advice
        objControl = New YL0PF
    Case "YL2PF"                    'Arrears with Additional Interest
        objControl = New YL2PF

... etc
End Select

AddHandler objControl.ProgressEvent, AddressOf OnProgressEvent
objControl.DoSomething()  ' <- lengthy process will raise ProgressEvent
....

Sub OnProgressEvent(sender as Object, e As ProgressEventArgs)
  ' Update your progress control - pay attention to "simon at rcl"'s comment above
  ' about making sure this is done on the GUI thread.  You will have to use Invoke 
  ' if the event will be fired from another thread.

  ' OP mentioned in a comment that they are using a BackgroundWorker so the
  ' ProgressEvent will be called in a background thread which can't change the
  ' UI.  So you would call its ReportProgress which will in turn raise its own
  ' ProgressChanged event but on the UI thread.
  backgroundWorker1.ReportProgress(CInt(e.Current / e.Maximum * 100))
End Sub 

Private Sub backgroundWorker1_ProgressChanged( _
            sender As Object, e As ProgressChangedEventArgs) _
            Handles backgroundWorker1.ProgressChanged
      ' This will be called on the UI thread, so we can update the ProgressBar
      Me.progressBar1.Value = e.ProgressPercentage
End Sub

【讨论】:

  • +1 感谢您的回答,我已经编辑了我的问题以使其更清晰并提供更多细节。
  • 请查看我的问题的编辑 - 我真的需要使用 backgroundworker_OnProgressChanged 事件更新表单 - 所以我需要能够绑定到引发的 alpsClient dll 上的事件按班级?
  • 没错,我已经修改了示例以显示使用 backgroundWorker.ReportProgress 方法。
猜你喜欢
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
相关资源
最近更新 更多