Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Update progressbar from another form using background worker

Posted on 2016-10-04
12
Medium Priority
?
106 Views
Last Modified: 2016-10-04
I have 'Form1' which has a background worker.  During process, a second overlay form 'Form2'  appears and I want a progress bar on that form to update the user on the progress.  How would I accomplish this?  Everything I had tried will not update the progress bar.  A simple .net example would suffice.
0
Comment
Question by:K-9
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
12 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41828039
The microsoft site has an example of how to update the GUI as a background worker does something:
https://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
0
 

Author Comment

by:K-9
ID: 41828050
The issue is when that my Progressbar is on a different form than my Backgroundworker.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41828071
Which is no problem at all.  
In the form with the background worker have a variable which is set to the form having the progress bar.
eg.
FormProgress frmProg
and then when you want to update the progressbar you use frmProg.ProgressBar1 instead of Me.ProgressBar1 as you would when running it on the same form.  Note you might have to change the accessibility of the variables to public (default might be private)


This is just the same as your other question involving accessing a backgroundworker from another form.  You just need to specify on which form it is.
0
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 

Author Comment

by:K-9
ID: 41828091
I've tried that, the progress bar is not updating.  

This is what I have (the form that has the progress bar is called CISMapOverlay)

 
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

        Dim frmPb = CISMapOverlay
        frmPb.ProgressBar1.Maximum = TotalAddresses
        frmPb.ProgressBar1.Value = e.ProgressPercentage

    End Sub

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41828132
>>the form that has the progress bar is called CISMapOverlay

Is that a variable name (which is what I told you to use, AND is set to the instance of the other form) or a class name
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41828137
ps.  I've used the code in the link I provided, added a second form and hooked it up the way I told you and it works perfectly.
0
 

Author Comment

by:K-9
ID: 41828152
I'm confused.  CISMapOverlay is the name of the form itself.  How would I go about what you are suggesting?  Code example would be awesome.
0
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 1000 total points
ID: 41828178
declare a variable
dim frmPB as CISMapOverlay

somewhere you would need to do something like
frmBackground.frmPB = Me
where frmBackground is an instance of the form with the background worker


This is pretty basic stuff concerning instances of objects.

dim i as integer = 42
dim j as integer
j does NOT have the value 42 because it is not the same instance of an integer as i
0
 

Author Comment

by:K-9
ID: 41828185
I already have frmPB declared.
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

        Dim frmPb = CISMapOverlay
        frmPb.ProgressBar1.Maximum = TotalAddresses
        frmPb.ProgressBar1.Value = e.ProgressPercentage

    End Sub

Open in new window


The form that has the background worker is frmGMapNet
 
frmGMapNet.frmPB = Me

Open in new window


gives me a compiler error.  Where would I put that code?
0
 
LVL 34

Assisted Solution

by:it_saige
it_saige earned 1000 total points
ID: 41828354
Here is a simple but effective example:

Form1.vb -
Imports System.Threading
Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Public Class Form1
	Private progress As CISMapOverlay

	Private Sub OnClick(sender As Object, e As EventArgs) Handles Button1.Click
		If Button1.Text = "Stop" Then
			BackgroundWorker1.CancelAsync()
		Else
			Button1.Text = "Stop"
			BackgroundWorker1.RunWorkerAsync()
		End If
	End Sub

	Private Sub OnDoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
		For Each [step] As Initialization In [Enum].GetValues(GetType(Initialization))
			If BackgroundWorker1.CancellationPending Then
				e.Cancel = True
				Return
			Else
				BackgroundWorker1.ReportProgress(CInt(CSng([step]) / CSng([Enum].GetValues(GetType(Initialization)).Length) * 100), [step].GetDesciption())
				Thread.Sleep(600)
			End If
		Next
	End Sub

	Private Sub OnProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
		If progress Is Nothing Then
			progress = New CISMapOverlay()
			progress.Show()
		End If
		progress.ProgressBar1.Value = e.ProgressPercentage
		progress.Label1.Text = CType(e.UserState, String)
	End Sub

	Private Sub OnRunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
		If progress IsNot Nothing Then
			progress.Close()
			progress.Dispose()
			progress = Nothing
		End If
		Button1.Text = "Start"
	End Sub
End Class

Module Extensions
	<Extension()> _
	Public Function GetDesciption(value As [Enum]) As String
		Try
			Dim [info] = value.GetType().GetField(value.ToString())
			Dim attributes = DirectCast([info].GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
			Return If(attributes.Length > 0, attributes(0).Description, value.ToString())
		Catch ex As Exception
			Return String.Empty
		End Try
	End Function
End Module

Enum Initialization
	<Description("Progress bar tester is starting")> Starting = 1
	<Description("All around the mulberry bush")> Mulberry
	<Description("The monkey chased the weasel.")> Monkey
	<Description("The monkey thought 'twas all in fun.")> Fun
	<Description("Pop! goes the weasel.")> Pop1
	<Description("A penny for a spool of thread,")> Thread
	<Description("A penny for a needle.")> Needle
	<Description("That's the way the money goes.")> Money1
	<Description("Pop! goes the weasel.")> Pop2
	<Description("Up and down the City Road,")> Road
	<Description("In and out of the Eagle,")> Eagle
	<Description("That's the way the money goes.")> Money2
	<Description("Pop! goes the weasel.")> Pop3
	<Description("Half a pound of tuppenney rice,")> Tuppenney
	<Description("Half a pound of treacle,")> Treacle
	<Description("Mix it up and make it nice,")> Nice
	<Description("Pop! goes the weasel.")> Pop4
	<Description("Progress bar tester is finishing")> Finishing
End Enum

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Me.BackgroundWorker1 = New System.ComponentModel.BackgroundWorker()
		Me.Button1 = New System.Windows.Forms.Button()
		Me.SuspendLayout()
		'
		'BackgroundWorker1
		'
		Me.BackgroundWorker1.WorkerReportsProgress = True
		Me.BackgroundWorker1.WorkerSupportsCancellation = True
		'
		'Button1
		'
		Me.Button1.Font = New System.Drawing.Font("Microsoft Sans Serif", 18.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
		Me.Button1.Location = New System.Drawing.Point(12, 12)
		Me.Button1.Name = "Button1"
		Me.Button1.Size = New System.Drawing.Size(172, 86)
		Me.Button1.TabIndex = 0
		Me.Button1.Text = "Start"
		Me.Button1.UseVisualStyleBackColor = True
		'
		'Form1
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(196, 110)
		Me.Controls.Add(Me.Button1)
		Me.Name = "Form1"
		Me.Text = "Form1"
		Me.ResumeLayout(False)

	End Sub
	Friend WithEvents BackgroundWorker1 As System.ComponentModel.BackgroundWorker
	Friend WithEvents Button1 As System.Windows.Forms.Button

End Class

Open in new window

CISMapOverlay.vb -
Public Class CISMapOverlay

End Class

Open in new window

CISMapOverlay.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class CISMapOverlay
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Me.ProgressBar1 = New System.Windows.Forms.ProgressBar()
		Me.Label1 = New System.Windows.Forms.Label()
		Me.SuspendLayout()
		'
		'ProgressBar1
		'
		Me.ProgressBar1.Location = New System.Drawing.Point(12, 42)
		Me.ProgressBar1.Name = "ProgressBar1"
		Me.ProgressBar1.Size = New System.Drawing.Size(551, 23)
		Me.ProgressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous
		Me.ProgressBar1.TabIndex = 0
		'
		'Label1
		'
		Me.Label1.AutoSize = True
		Me.Label1.Location = New System.Drawing.Point(9, 9)
		Me.Label1.Name = "Label1"
		Me.Label1.Size = New System.Drawing.Size(39, 13)
		Me.Label1.TabIndex = 1
		Me.Label1.Text = "Label1"
		'
		'CISMapOverlay
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(575, 75)
		Me.ControlBox = False
		Me.Controls.Add(Me.Label1)
		Me.Controls.Add(Me.ProgressBar1)
		Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow
		Me.MaximizeBox = False
		Me.MinimizeBox = False
		Me.Name = "CISMapOverlay"
		Me.ShowIcon = False
		Me.ShowInTaskbar = False
		Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
		Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
		Me.Text = "CISMapOverlay"
		Me.TopMost = True
		Me.ResumeLayout(False)
		Me.PerformLayout()

	End Sub
	Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar
	Friend WithEvents Label1 As System.Windows.Forms.Label
End Class

Open in new window


-saige-
0
 

Author Closing Comment

by:K-9
ID: 41828439
Thank you, I realized in my other code I already had a reference to the form and because I was using a new reference to the form it was never updating the progress bar.  Using the previous instance worked.  I feel like an idiot, but thank you!
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41828496
Everyone has bad days.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question