Visual Studio Development Bookmark and Share   
 index > Visual Basic Express Edition > Unable to update progress from class
 

Unable to update progress from class

I've done significant amount of searching but have not found what I'm looking for our how I can apply it to my case. What I have now is on click, I start a thread that calls a class. I want the class to update the form's progress bar, but I have had no luck with this. I have read about BackgroundWorker but it seems that all the examples are within the same form.  The following code is what I had before messing with BackgroundWorker class.

Calling the class:

Dim testFunction As New Class_GetStoreVersion
t = New Threading.Thread(AddressOf testFunction.buildVersionForm)
t.Start()

The class where work is done

Public Function buildVersionForm() As Boolean

	Dim x As Integer = 0
	Dim storeVersionLocation As New XmlDocument
	Dim xlsApp As Excel.Application
	Dim xlsWB As Excel.Workbook
	Dim xlsSheet As Excel.Worksheet
	Dim xlsRange As Excel.Range
	Dim formCounter As New StartForm
	Dim progressBar = formCounter.version_ProgressBar
	Dim ISCENTRLPF_Value As String
	Dim VERSIONNBR_Value As String
	Dim SRVPRGVNBR_Value As String
	Dim CLIENTVNBR_Value As String
	Dim GSCKTCFGPF_Value As String
	Dim libraryName As String

	storeVersionLocation.Load(Application.StartupPath & "\\properties.xml")
	Dim versionPath As String = storeVersionLocation.GetElementsByTagName("store_versions_file").Item(0).InnerText.ToString
	Dim xlsxLocation As String = storeVersionLocation.GetElementsByTagName("store_version_template").Item(0).InnerText.ToString
	storeVersionLocation.Load(versionPath)

	Dim storeNode As XmlNode = storeVersionLocation.SelectSingleNode("versions_properties/store_row")
	Dim stores As XmlNodeList = storeVersionLocation.SelectSingleNode("versions_properties/store_row").ChildNodes

	xlsApp = New Excel.Application
	xlsApp.Visible = False
	xlsWB = xlsApp.Workbooks.Open(xlsxLocation)
	xlsSheet = xlsWB.Worksheets("Sheet1")

	xlsSheet.Unprotect("")

	progressBar.Minimum = 0
	progressBar.Maximum = stores.Count
	progressBar.Step = stores.Count
	progressBar.Visible = True

	For x = 0 To stores.Count
		Try
			conn = New Odbc.OdbcConnection("Driver={iSeries Access ODBC Driver};System=" & stores.Item(x).LocalName & _
										   ";Uid=;Pwd=")
			conn.Open()

			ISCENTRLPF_Value = getISCENTRLPF(conn)

			If ISCENTRLPF_Value = "Y" Then
				xlsRange = xlsSheet.Range(storeVersionLocation.GetElementsByTagName("iscentral_column").Item(0).InnerText.ToString() & _
										  stores.Item(x).InnerText)
				ISCENTRLPF_Value = xlsRange.Value
				Dim formattedStoreName As String = stores.Item(x).LocalName
				formattedStoreName = Left(formattedStoreName, 6)
				formattedStoreName = formattedStoreName & "dtlb"
				libraryName = formattedStoreName
			Else
				libraryName = "STRDATALB"
			End If

			' Database Version Number
			VERSIONNBR_Value = getVERSIONNBR(conn, libraryName)
			xlsRange = xlsSheet.Range(storeVersionLocation.GetElementsByTagName("versionnbr_column").Item(0).InnerText.ToString() & _
					  stores.Item(x).InnerText)
			xlsRange.Value = VERSIONNBR_Value
			' Server Version Number
			SRVPRGVNBR_Value = getSRVPRGVNBR(conn, libraryName)
			xlsRange = xlsSheet.Range(storeVersionLocation.GetElementsByTagName("srvprgvnbr_column").Item(0).InnerText.ToString() & _
					  stores.Item(x).InnerText)
			xlsRange.Value = SRVPRGVNBR_Value
			' Client Version Number
			CLIENTVNBR_Value = getCLIENTVNBR(conn, libraryName)
			xlsRange = xlsSheet.Range(storeVersionLocation.GetElementsByTagName("clientvnbr_column").Item(0).InnerText.ToString() & _
					  stores.Item(x).InnerText)
			xlsRange.Value = CLIENTVNBR_Value
			' Port Number
			GSCKTCFGPF_Value = getGSCKTCFGPF(conn, libraryName)
			xlsRange = xlsSheet.Range(storeVersionLocation.GetElementsByTagName("gscktcfgpf_column").Item(0).InnerText.ToString() & _
					  stores.Item(x).InnerText)
			xlsRange.Value = GSCKTCFGPF_Value

			conn = Nothing
		Catch ex As Exception
			Debug.WriteLine(ex.Message)
			conn = Nothing
		End Try
		progressBar.Increment(1)
	Next
	xlsSheet.Protect("")
	progressBar.Visible = False
	xlsApp.Visible = True
End Function
 




Like I said, I'm not too familiar on BackgroundWorker, but I have tried to read before posting. All the examples show the BackgroundWorker in the same form as the progress bar, so I'm not sure how to apply it to my case. If I need to change how I have it and move the "buildVersionForm" out of the class and into the form then I will.

Thank you,
Drew


  • Edited byDrew_M_ Tuesday, October 13, 2009 8:30 PM
  • Edited byDrew_M_ Tuesday, October 13, 2009 8:33 PM
  •  
Drew_M_  Tuesday, October 13, 2009 6:14 PM

Here are four sample classes.

Class ProgressBarData
    Public Minimum As Integer
    Public Maximum As Integer
    Public Value As Integer
    Public Sub New()
        Minimum = 0
        Maximum = 0
        Value = 0
    End Sub
End Class


'GetStoreVersion.vb

Imports System.ComponentModel
Imports System.Threading

Public Class GetStoreVersion
    Dim worker As BackgroundWorker
    Public Event Disposed(ByVal sender As Object, ByVal e As EventArgs)
    Public Event RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
    Public Event ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
    Public Event DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)


    Public Sub New()
        worker = New BackgroundWorker()
        worker.WorkerReportsProgress = True
        worker.WorkerSupportsCancellation = True
        AddHandler worker.Disposed, AddressOf worker_Disposed
        AddHandler worker.RunWorkerCompleted, AddressOf worker_RunWorkerCompleted
        AddHandler worker.ProgressChanged, AddressOf worker_ProgressChanged
        AddHandler worker.DoWork, AddressOf worker_DoWork

    End Sub

    Private Sub worker_Disposed(ByVal sender As Object, ByVal e As EventArgs)
        ' Dispose of unmanaged resources used by BGW here.
        RaiseEvent Disposed(sender, e)
    End Sub
    Private Sub worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        RaiseEvent RunWorkerCompleted(sender, e)
    End Sub
    Private Sub worker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        RaiseEvent ProgressChanged(sender, e)
    End Sub
    Private Sub worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        ' Note that all referenced variables have a scope limited to this Sub
        Dim data As New ProgressBarData()
        Dim i As Integer
        For i = 0 To 100
            Thread.Sleep(100)
            data.Minimum = 0
            data.Maximum = 100
            data.Value = i
            worker.ReportProgress(i, data)
        Next
    End Sub

    Public Function GetVersion() As Boolean
        Me.worker.RunWorkerAsync(New ProgressBarData())
        Return True
    End Function

End Class


' BuildVersionForm.vb

Imports System.ComponentModel
Imports System.Threading


Public Class BuildVersionForm
    Dim version As GetStoreVersion

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub
    Public Sub New(ByVal version As GetStoreVersion)
        Me.New()
        Me.version = version
        AddHandler version.ProgressChanged, AddressOf version_ProgressChanged
    End Sub
    Private Sub version_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        Dim userData As ProgressBarData = CType(e.UserState, ProgressBarData)
        Me.ProgressBar1.Minimum = userData.Minimum
        Me.ProgressBar1.Maximum = userData.Maximum
        Me.ProgressBar1.Value = userData.Value
    End Sub

End Class

 

Imports System.ComponentModel
Imports System.Threading

Public Class Form1
    Dim version As GetStoreVersion
    Dim versionForm As BuildVersionForm

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.ProgressBar1.Style = ProgressBarStyle.Continuous
    End Sub

    Private Sub version_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        Dim userData As ProgressBarData = CType(e.UserState, ProgressBarData)
        Me.ProgressBar1.Minimum = userData.Minimum
        Me.ProgressBar1.Maximum = userData.Maximum
        Me.ProgressBar1.Value = userData.Value
    End Sub

    Private Sub version_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        Me.versionForm.Close()
    End Sub

    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click

        version = New GetStoreVersion()
        AddHandler version.ProgressChanged, AddressOf version_ProgressChanged
        AddHandler version.RunWorkerCompleted, AddressOf version_RunWorkerCompleted
        '
        Me.versionForm = New BuildVersionForm(version)
        versionForm.Show()
        version.GetVersion()
    End Sub
End Class


Mark the best replies as answers. "Fooling computers since 1971."
  • Marked As Answer byDrew_M_ Wednesday, October 14, 2009 8:10 PM
  •  
Rudedog2  Tuesday, October 13, 2009 11:19 PM
I posted a sample application.  Not something to plug-n-play with your application.
I tried to name stuff with names similar to what you have posted about your app.
Form1 needs a button and a progressbar, while the other form simply needs a progressbar.

As for where does stuff go, It is always best to put one class per file. 
Put each of the four classes into their own file in a new test project for WinForms, so that you can learn the new concepts. 


    Private Sub worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        ' Note that all referenced variables have a scope limited to this Sub
        Dim data As New ProgressBarData()
        Dim i As Integer
        For i = 0 To 100
            Thread.Sleep(100)
            data.Minimum = 0
            data.Maximum = 100
            data.Value = i
            worker.ReportProgress(i, data)
        Next
    End Sub


Remove all of that stuff in your Sub that modifies the control directly. 
The call to worker.ReportProgress performs the update of the form and its' controls. 
That method call causes the ProgressChanged event to be fired, and 'marshals' objects back to the main UI thread.
I call Thread.Sleep() simply to slow it down.  Try changing the value to be Thread.Sleep(25)




That Sub contains the loop that is supposed to imitate yours.
Mark the best replies as answers. "Fooling computers since 1971."
  • Marked As Answer byDrew_M_ Thursday, October 15, 2009 5:21 PM
  •  
Rudedog2  Wednesday, October 14, 2009 10:42 PM

Hello,

The background worker is the best type to use.
I wrote the examples and info at the very bottom of the page.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx


You should describe the problems you had with the BGW. 
I assume you wish to abandon it, I encourage you to use it.

I hope you posted enough code to understand my response. 
I assume your posted code is not part of a form, but elsewhere.
Simply use the worker.ReportProgress( Integer, Object) method within your main loop.

Define a class to hold what ever data you need to pass to the form from the worker thread.
I noticed that you are currently setting the progressbar.Step property incorrectly. 
Try setting it to 1 in that example, but I still encourage a BGW. It was designed for this purpose.

Class ProgressBarData
    Dim Minimum As Integer
    Dim Maximum As Integer
    Dim Value As Integer
End Class.

You will instantiate that class and set the values within your loop.
Most of the above code---or at least some form of it that does the same job---will appear within the DoWork handler.
Pass the instance and the current loop index in the worker.ReportProgress method. 
The index will need to be normalized to 0 to 100 if you intend to pass it.  Otherwise simply pass 0 or 1, as a binary flag.

Some would say to define public subs on your form, and simply use those as the targets for thw BGW event handlers.  Don't.
I would not expose the stuff as public, especially for something that is commercial.
A better practice would be to define events in your class that you will fire within private BGW event handlers inside your undescribed class.

I assume that your form creates an instance of this undescribed class. 
So I assume that the form can subscribe to events fired by the class instance.
Inside your class simply pass the parameter objects to the new event and fire it.

One of the events you will need to subscribe to from the instance inside of the form is ProgressChanged.
The object you passed as a parameter will get returned as the UserState property of the EventArgs parameter in the event handler.
You will need to cast the object to your custom class prior to use.  Now you have 3 values you can use to set your progressbar.

Hope this helps.

Rudy   =8^D

Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Tuesday, October 13, 2009 8:03 PM
I'll read through that one, I'll probably have a few questions.
Drew_M_  Tuesday, October 13, 2009 8:44 PM
I'm just not understanding this, I'll try to convey better what I'm trying to do.

File: StartForm.vb
Public Class StartForm
   Private Sub start_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles start_Button.Click

   ' Call buildVersionForm<br />
<br />
   End Sub
EndClass 
File: Class_GetStoreVersion.vb
Public Class Class_GetStoreVersion
   Public Function buildVersionForm() As Boolean

   ' Build spreadsheet, and update progress bar in StartForm<br />
<br />
End Class
What's throwing me off is "Me", I can't use this when trying to update a different class? I'm not getting how to apply this to my case, I know very little about threads, so talk down to me if need be.
Drew_M_  Tuesday, October 13, 2009 9:55 PM
Which form has the intance of Class_GetStoreVersion?
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Tuesday, October 13, 2009 10:19 PM

Here are four sample classes.

Class ProgressBarData
    Public Minimum As Integer
    Public Maximum As Integer
    Public Value As Integer
    Public Sub New()
        Minimum = 0
        Maximum = 0
        Value = 0
    End Sub
End Class


'GetStoreVersion.vb

Imports System.ComponentModel
Imports System.Threading

Public Class GetStoreVersion
    Dim worker As BackgroundWorker
    Public Event Disposed(ByVal sender As Object, ByVal e As EventArgs)
    Public Event RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
    Public Event ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
    Public Event DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)


    Public Sub New()
        worker = New BackgroundWorker()
        worker.WorkerReportsProgress = True
        worker.WorkerSupportsCancellation = True
        AddHandler worker.Disposed, AddressOf worker_Disposed
        AddHandler worker.RunWorkerCompleted, AddressOf worker_RunWorkerCompleted
        AddHandler worker.ProgressChanged, AddressOf worker_ProgressChanged
        AddHandler worker.DoWork, AddressOf worker_DoWork

    End Sub

    Private Sub worker_Disposed(ByVal sender As Object, ByVal e As EventArgs)
        ' Dispose of unmanaged resources used by BGW here.
        RaiseEvent Disposed(sender, e)
    End Sub
    Private Sub worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        RaiseEvent RunWorkerCompleted(sender, e)
    End Sub
    Private Sub worker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        RaiseEvent ProgressChanged(sender, e)
    End Sub
    Private Sub worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        ' Note that all referenced variables have a scope limited to this Sub
        Dim data As New ProgressBarData()
        Dim i As Integer
        For i = 0 To 100
            Thread.Sleep(100)
            data.Minimum = 0
            data.Maximum = 100
            data.Value = i
            worker.ReportProgress(i, data)
        Next
    End Sub

    Public Function GetVersion() As Boolean
        Me.worker.RunWorkerAsync(New ProgressBarData())
        Return True
    End Function

End Class


' BuildVersionForm.vb

Imports System.ComponentModel
Imports System.Threading


Public Class BuildVersionForm
    Dim version As GetStoreVersion

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub
    Public Sub New(ByVal version As GetStoreVersion)
        Me.New()
        Me.version = version
        AddHandler version.ProgressChanged, AddressOf version_ProgressChanged
    End Sub
    Private Sub version_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        Dim userData As ProgressBarData = CType(e.UserState, ProgressBarData)
        Me.ProgressBar1.Minimum = userData.Minimum
        Me.ProgressBar1.Maximum = userData.Maximum
        Me.ProgressBar1.Value = userData.Value
    End Sub

End Class

 

Imports System.ComponentModel
Imports System.Threading

Public Class Form1
    Dim version As GetStoreVersion
    Dim versionForm As BuildVersionForm

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.ProgressBar1.Style = ProgressBarStyle.Continuous
    End Sub

    Private Sub version_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        Dim userData As ProgressBarData = CType(e.UserState, ProgressBarData)
        Me.ProgressBar1.Minimum = userData.Minimum
        Me.ProgressBar1.Maximum = userData.Maximum
        Me.ProgressBar1.Value = userData.Value
    End Sub

    Private Sub version_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        Me.versionForm.Close()
    End Sub

    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click

        version = New GetStoreVersion()
        AddHandler version.ProgressChanged, AddressOf version_ProgressChanged
        AddHandler version.RunWorkerCompleted, AddressOf version_RunWorkerCompleted
        '
        Me.versionForm = New BuildVersionForm(version)
        versionForm.Show()
        version.GetVersion()
    End Sub
End Class


Mark the best replies as answers. "Fooling computers since 1971."
  • Marked As Answer byDrew_M_ Wednesday, October 14, 2009 8:10 PM
  •  
Rudedog2  Tuesday, October 13, 2009 11:19 PM
I would appreciate it if somone who is more adept at VB than me can explain why the ProgressBar on Form1 does change to a Continous style.
I think my VB is kind of weak.
The display remains as blocks, despite the fact that I can make this change to one of the methods in Form1 class.

  Private Sub version_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        Dim userData As ProgressBarData = CType(e.UserState, ProgressBarData)
        Me.ProgressBar1.Minimum = userData.Minimum
        Me.ProgressBar1.Maximum = userData.Maximum
        Me.ProgressBar1.Value = userData.Value
        Me.Text = Me.ProgressBar1.Style.ToString()
    End Sub


Thanks, ahead of time.

Rudy  =8^D
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Tuesday, October 13, 2009 11:32 PM
Thank you for your time and effort.

I will proceed to bash my head into a wall.
Drew_M_  Wednesday, October 14, 2009 8:16 PM
Thank you for your time and effort.

I will proceed to bash my head into a wall.


NO!  For what?

Ask questions if you do not understand how it works.
Step one to understanding that code is understanding how events and event handlers work.

Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, October 14, 2009 8:27 PM
I guess I'm being very dense about this. I've tried to apply the code to what I have but have been less than successful. I'm very new to this so that's not helping my cause, as I don't think I'm conveying what I'm trying to do very well. Your examples were very helpful, don't get me wrong, its just that I can't figure how to apply it to what I'm doing.

Questions that I had.
Where do I need to put the "Class ProgressBarData", does this belong in its own .VB? or does this get appended to one of the other .VB files
I'm also not too sure what the form1 is all about, as I only have 2 .VB files, the StartForm.VB and Class_GetStoreVersion.VB

I basically tried to copy and paste what you've written but it didn't like that too much.
Drew_M_  Wednesday, October 14, 2009 10:20 PM
I posted a sample application.  Not something to plug-n-play with your application.
I tried to name stuff with names similar to what you have posted about your app.
Form1 needs a button and a progressbar, while the other form simply needs a progressbar.

As for where does stuff go, It is always best to put one class per file. 
Put each of the four classes into their own file in a new test project for WinForms, so that you can learn the new concepts. 


    Private Sub worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        ' Note that all referenced variables have a scope limited to this Sub
        Dim data As New ProgressBarData()
        Dim i As Integer
        For i = 0 To 100
            Thread.Sleep(100)
            data.Minimum = 0
            data.Maximum = 100
            data.Value = i
            worker.ReportProgress(i, data)
        Next
    End Sub


Remove all of that stuff in your Sub that modifies the control directly. 
The call to worker.ReportProgress performs the update of the form and its' controls. 
That method call causes the ProgressChanged event to be fired, and 'marshals' objects back to the main UI thread.
I call Thread.Sleep() simply to slow it down.  Try changing the value to be Thread.Sleep(25)




That Sub contains the loop that is supposed to imitate yours.
Mark the best replies as answers. "Fooling computers since 1971."
  • Marked As Answer byDrew_M_ Thursday, October 15, 2009 5:21 PM
  •  
Rudedog2  Wednesday, October 14, 2009 10:42 PM
I just got the October 13, 2009 11:19 PM post working, that's pretty neat.

Now I have to go back and figure what just happened.

Thanks again for all the help.

-Drew
Drew_M_  Thursday, October 15, 2009 5:19 PM
Pay very close attention to the variable named "version" on Form1. 
An instance of that variable is passed to the BuildVersionForm variable in form1 through the constructor.

Brush up on events and delegates if you are not very good with those topics.

Happy Coding.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Thursday, October 15, 2009 6:20 PM
It's getting close it seems but I do have one problem.

Here's what I have as of now

Main Form:

Public Class StartForm
    Dim version As Class_GetStoreVersion
    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.ProgressBar1.Style = ProgressBarStyle.Continuous
    End Sub
    Private Sub version_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        Dim userData As Class_ProgressBarData = CType(e.UserState, Class_ProgressBarData)
        Me.ProgressBar1.Minimum = userData.Minimum
        Me.ProgressBar1.Maximum = userData.Maximum
        Me.ProgressBar1.Value = userData.Value
    End Sub

    Private Sub version_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        StoreVersionForm.Close()
    End Sub

Private Sub start_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles start_Button.Click
                version = New Class_GetStoreVersion
                AddHandler version.ProgressChanged, AddressOf version_ProgressChanged
                AddHandler version.RunWorkerCompleted, AddressOf version_RunWorkerCompleted
                Me.version = New Class_GetStoreVersion
                version.buildVersionForm()
End Class
Progress Bar Data:
Public Class Class_ProgressBarData
    Public Minimum As Integer
    Public Maximum As Integer
    Public Value As Integer
    Public Sub New()
        Minimum = 0
        Maximum = 0
        Value = 0
    End Sub
End Class
And last the class that builds the xls:
Imports System.ComponentModel
Imports System.Threading
Imports System.Data
Imports System.Data.OleDb
Imports ADODB


Public Class Class_GetStoreVersion

    Dim worker As BackgroundWorker
    Public Event Disposed(ByVal sender As Object, ByVal e As EventArgs)
    Public Event RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
    Public Event ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
    Public Event DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    Dim conn As New Odbc.OdbcConnection
    Dim query As New Odbc.OdbcCommand
    Dim dr As Odbc.OdbcDataReader

    Public Sub New()
        worker = New BackgroundWorker()
        worker.WorkerReportsProgress = True
        worker.WorkerSupportsCancellation = True
        AddHandler worker.Disposed, AddressOf worker_Disposed
        AddHandler worker.RunWorkerCompleted, AddressOf worker_RunWorkerCompleted
        AddHandler worker.ProgressChanged, AddressOf worker_ProgressChanged
        AddHandler worker.DoWork, AddressOf worker_DoWork
    End Sub

    Public Function buildVersionForm() As Boolean
        Me.worker.RunWorkerAsync(New Class_ProgressBarData())
        Return True
    End Function

    Private Sub worker_Disposed(ByVal sender As Object, ByVal e As EventArgs)
        ' Dispose of unmanaged resources used by BGW here.
        RaiseEvent Disposed(sender, e)
    End Sub

    Private Sub worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        RaiseEvent RunWorkerCompleted(sender, e)
    End Sub

    Private Sub worker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        RaiseEvent ProgressChanged(sender, e)
    End Sub

     Private Sub worker_DoWork(ByVal sender As Object, ByVal  e   As DoWorkEventArgs)<br />

        Dim data As New Class_ProgressBarData
        For x = 0 To stores.Count

           data.Minimum = 0
           data.Maximum = stores.<span style="color: blue;">Count</span>
           data.Value = x
           worker.ReportProgress(x, data)

        Next

End sub



The problem is when I call "version.buildVersionForm()" from StartForm, it will go into Class_GetStoreVersion, step into the "buildVersionForm()" then immediatly exit without doing anything. The strange part is that it will open Excel, but nothing happens, and the progress bar is not updated. I'll try to mess with it more, though if you can see something that would be nice.

EDIT:
It's building the xls, just not updating the progress bar.

-Drew
  • Edited byDrew_M_ Friday, October 16, 2009 2:57 PM
  • Edited byDrew_M_ Friday, October 16, 2009 2:56 PM
  •  
Drew_M_  Thursday, October 15, 2009 8:55 PM
I assume your code for 'building the xls (loop)' is similar to your initial post.

If you add this loop where you have that comment.

Private Sub worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        ' Note that all referenced variables have a scope limited to this Sub
        Dim data As New ProgressBarData()
        Dim i As Integer
        For i = 0 To 100
            Thread.Sleep(100)
            data.Minimum = 0
            data.Maximum = 100
            data.Value = i
            worker.ReportProgress(i, data)   '  here I am reporting progress inside of the loop
        Next

    End Sub


It should update the ProgressBar.  Note that I call worker.ReportProgress from inside of the loop, not after the loop has completed.


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Friday, October 16, 2009 12:21 PM

I had

data.Minimum = 0
data.Maximum = stores.Count

Outside the loop but the .ReportProgress inside the loop, I didn't show that very well.


For x = 0 To stores.Count

   data.Minimum = 0
   data.Maximum = stores.Count
   data.Value = x
   worker.ReportProgress(x, data)

Next


That's what I have (more or less) now, but still not updating. So close, I can feel it.
Drew_M_  Friday, October 16, 2009 2:29 PM
If you got my sample to work, you should be on a downhill ride.
I hope you still have my sample in separate test project.  (Get used to making and saving test projects!)

That snippet you just posted doesn't update?
Hmmm.  Try setting a breakpoint on the ReportsProgress method call. 
Then step through it.  See if the event handler on the form is getting invoked.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Friday, October 16, 2009 3:51 PM
I have no idea why, but it works. I cannot explain why it works now, I will not quesiton it, and I will never touch it again.

I stepped through it, that's all I remember doing.

Well, thank you for all the help.

I owe you lunch if you're ever in AZ.
  • Proposed As Answer byRudedog2 Friday, October 16, 2009 4:00 PM
  •  
Drew_M_  Friday, October 16, 2009 3:54 PM
No idea, huh. 
Your solution is a textbook example of event-driven programming.

Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Friday, October 16, 2009 4:03 PM

You can use google to search for other answers

Custom Search

More Threads

• Add elements from an Array to Drop down box
• filling a datagrid
• From VB Express to Visual Studio 2005
• Help needed with Telnet API
• Is there a restriction on the size of vectors with express edition?
• My if statemement is being skipped...why?
• play audio files
• Gradient background for tolstrip and menus
• Why wouldnt app start when called for by other app
• vb/directx8 issue