Solved

Update progressbar from another form using background worker

Posted on 2016-10-04
12
67 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
Webinar: Aligning, Automating, Winning

Join Dan Russo, Senior Manager of Operations Intelligence, for an in-depth discussion on how Dealertrack, leading provider of integrated digital solutions for the automotive industry, transformed their DevOps processes to increase collaboration and move with greater velocity.

 

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 250 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 250 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

Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

Question has a verified solution.

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

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…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

751 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