[RESOLVED] Updating Progress Bar on a separate form
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: [RESOLVED] Updating Progress Bar on a separate form

  1. #1
    Join Date
    Jan 2011
    Posts
    11

    [RESOLVED] Updating Progress Bar on a separate form

    I am attempting to update a progress bar on a separate form.

    At the moment I have a massive bit of code which constantly changes how long it takes to complete depending on the options the user selects. The code takes place in a background worker on one form. The progress bar is named PBar and I currently have it set up in increments throughout the coding to update it. I have the call method which when the code meets a progress update it will complete the update to the progress bar but this does not happen as I cannot reference the bar on the separate form called Splash.

    Please could you give me some steps/ code to complete this task,
    Thanks

  2. #2
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: Updating Progress Bar on a separate form

    You could always create a public property in the splash form that allows you to set the value of the progress bar. Something like...

    Code:
    public partial class Splash : Form
    {
       public Splash()
       {
          InitializeComponent();
       }
    
       public int ProgressBarValue
       {
          get { return (this.progressBar.Value); }
          set { this.progressBar.Value = value; }
       }
    }
    Then just reference it from your main form.

    Code:
    splash.ProgressBarValue = 10; // or whatever the progress is between your ProgressBar's minimum and maximum values.
    Last edited by RaleTheBlade; February 14th, 2011 at 09:58 AM.
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

  3. #3
    Join Date
    Jan 2011
    Posts
    11

    Re: Updating Progress Bar on a separate form

    I understand what you mean from there but on the main form it still doesn't recognise the calling of that process.
    I'm not sure why it does that though.

  4. #4
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: Updating Progress Bar on a separate form

    How are you creating an instance of the Splash form? Do you have a reference to it from your main application form?
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

  5. #5
    Join Date
    Jan 2011
    Posts
    11

    Re: Updating Progress Bar on a separate form

    It is being referenced at the beginning of the background worker with
    Code:
                Form Splash = new Splash();
                Splash.Show();
    I've tried placing it in different positions as well but it doesn't seem to make a difference.

  6. #6
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: Updating Progress Bar on a separate form

    Ok, so you 're creating an instance of it on a BackgroundWorker object thread. Is there alot of code in your DoWork eventhandler? Can you post it so we can see what's going on? What might be happening is that you're creating this instance of Splash and showing it on a background thread and then the thread is ending, which would cause the form to be disposed of automatically.
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

  7. #7
    Join Date
    Jan 2011
    Posts
    11

    Re: Updating Progress Bar on a separate form

    Yes there is alot of code
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace Tourny_Manager
    {
    
        public partial class CreateDraws : Form
        {
            
            public CreateDraws()
            {
                InitializeComponent();
            }
    
            private void CreateDraws_Load(object sender, EventArgs e)
            {
                // TODO: This line of code loads data into the 'tournyManagerDataSet.Tournament' table. You can move, or remove it, as needed.
                this.tournamentTableAdapter.Fill(this.tournyManagerDataSet.Tournament);
                // TODO: This line of code loads data into the 'tournyManagerDataSet.TournamentDetails' table. You can move, or remove it, as needed.
                this.tournamentDetailsTableAdapter.Fill(this.tournyManagerDataSet.TournamentDetails);
    
    
                this.tChoice.SelectedIndex = -1;
            }
    
            private void btnCreateDraws_Click(object sender, EventArgs e)
            {
                 if (tChoice.Text != "")
                 {
    
                    if ((GU11.Text == "") || (BU11.Text == "") || (GU13.Text == "") || (BU13.Text == "") || (GU15.Text == "") || (BU15.Text == "") || (GU17.Text == "") || (BU17.Text == "") || (GU19.Text == "") || (BU19.Text == ""))
                    {
                        MessageBox.Show("Some Age groups have not been selected, Please confirm all of them, even if you do not require them.", "Age Group Selection", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
    
    
                        SaveFileDialog DialogSave = new SaveFileDialog();
                        DialogSave.DefaultExt = "xls";
                        DialogSave.Filter = "Excel File (*.xls)|*.xls|All files (*.*)|*.*";
                        DialogSave.AddExtension = true;
                        DialogSave.RestoreDirectory = true;
                        DialogSave.Title = "Where do you want to save the file?";
                        DialogSave.InitialDirectory = @"C:/";
    
    
                        if (DialogSave.ShowDialog() == DialogResult.OK)
                        {
                            MessageBox.Show("You selected the file: " + DialogSave.FileName);
    
                            backgroundWorker1.RunWorkerAsync(new string[] { tChoice.Text, BU19.Text, GU19.Text, BU17.Text, GU17.Text, BU15.Text, GU15.Text, BU13.Text, GU13.Text, BU11.Text, GU11.Text, DialogSave.FileName });
                           
    
                            
    
                            
                        }
                        else
                        {
                            MessageBox.Show("You hit cancel or closed the dialog. The draws will not be created");
                        }
    
    
                    }
                 }
                else
                {
                    MessageBox.Show("Please select a tournament.", "No Tournament Selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
    
            }
    
            private void lblDrawType_Click(object sender, EventArgs e)
            {
    
            }
    
            private void tChoice_SelectedIndexChanged(object sender, EventArgs e)
            {
                DataTable Comp = this.tournyManagerDataSet.Tournament;
    
                DataRow[] RowTotal = Comp.Select("[Age Group] = 'BU19' AND [Tournament] = '" + tChoice.Text + "'");
                int Entrants = RowTotal.Count();
                lblNOGU11.Text = System.Convert.ToString(Entrants);
            }
    
            
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
    
                Form Splash = new Splash();
                Splash.Show();
    
                
    
                string[] Params = e.Argument as String[];
                string tChoice = Params[0];
                string BU19 = Params[1];
                string GU19 = Params[2];
                string BU17 = Params[3];
                string GU17 = Params[4];
                string BU15 = Params[5];
                string GU15 = Params[6];
                string BU13 = Params[7];
                string GU13 = Params[8];
                string BU11 = Params[9];
                string GU11 = Params[10];
                string FileName = Params[11];
    
                        Excel.Application oXL;
                        Excel.Workbook oWB;
                        Excel.Worksheet oSheet;
                        Excel.Range oRange;
    
                        // Start Excel and get Application object. 
                        oXL = new Excel.Application();
    
                        // Set some properties 
                        // oXL.Visible = true;
                        oXL.DisplayAlerts = false;
    
                        // Get a new workbook. 
                        string location = @"C:\Documents and Settings\Nick\My Documents\Visual Studio 2008\Projects\Tourny Manager (Export Test)\Test.xls";
                        oWB = oXL.Workbooks.Open(location, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
    
                        backgroundWorker1.ReportProgress(1);
    
                        // Process the DataTable 
                        // BE SURE TO CHANGE THIS LINE TO USE *YOUR* DATATABLE 
                        DataTable dt = this.tournyManagerDataSet.Tournament;
                        try
                        {
                            dt.Columns.Remove("England Squash Number");
                            dt.Columns.Remove("Home Phone");
                            dt.Columns.Remove("Mobile Phone");
                            dt.Columns.Remove("Email");
                            dt.Columns.Remove("Email 2");
                            dt.Columns.Remove("T-Shirt Size");
                            dt.Columns.Remove("Position");
                        }
                        catch
                        {
                        }
    
    
    
    
                        DataRow[] Rows;
                        int rowCount;
    
    
                        backgroundWorker1.ReportProgress(2);
                        //BU19
    
                        Rows = dt.Select("[Age Group] = 'BU19' AND [Tournament] = '" + tChoice + "'", "Seeding");
                        if (BU19 == "8 Monrad")
                        {
                            // Get the active sheet 
                            oSheet = (Excel.Worksheet)oWB.Sheets["8 M"];
                            oSheet.Copy(Type.Missing, oWB.Sheets["Winners"]);
                            oSheet = (Excel.Worksheet)oWB.Sheets["8 M (2)"];
                            oSheet.Name = "BU19";
    
                            rowCount = 1;
                            foreach (DataRow dr in Rows)
                            {
                                rowCount += 1;
                                for (int i = 1; i < dt.Columns.Count + 1; i++)
                                {
                                    // Add the header the first time through 
                                    if (rowCount == 2)
                                    {
                                        oSheet.Cells[1, i + 115] = dt.Columns[i - 1].ColumnName;
                                    }
                                    oSheet.Cells[rowCount, i + 115] = dr[i - 1].ToString();
                                }
                            }
    
                            // Resize the columns 
                            oRange = oSheet.get_Range(oSheet.Cells[1, 115],
                                          oSheet.Cells[rowCount, dt.Columns.Count + 115]);
                            oRange.EntireColumn.AutoFit();
    
                        }
                        else if (BU19 == "16 Monrad")
                        {
                            // Get the active sheet 
                            oSheet = (Excel.Worksheet)oWB.Sheets["16 M"];
                            oSheet.Copy(Type.Missing, oWB.Sheets["Winners"]);
                            oSheet = (Excel.Worksheet)oWB.Sheets["16 M (2)"];
                            oSheet.Name = "BU19";
    
    
                            rowCount = 1;
                            foreach (DataRow dr in Rows)
                            {
                                rowCount += 1;
                                for (int i = 1; i < dt.Columns.Count + 1; i++)
                                {
                                    // Add the header the first time through 
                                    if (rowCount == 2)
                                    {
                                        oSheet.Cells[1, i + 115] = dt.Columns[i - 1].ColumnName;
                                    }
                                    oSheet.Cells[rowCount, i + 115] = dr[i - 1].ToString();
                                }
                            }
    
                            // Resize the columns 
                            oRange = oSheet.get_Range(oSheet.Cells[1, 115],
                                          oSheet.Cells[rowCount, dt.Columns.Count + 115]);
                            oRange.EntireColumn.AutoFit();
                        }
                        else if (BU19 == "32 Monrad")
                        {
                            // Get the active sheet 
                            oSheet = (Excel.Worksheet)oWB.Sheets["32 M"];
                            oSheet.Copy(Type.Missing, oWB.Sheets["Winners"]);
                            oSheet = (Excel.Worksheet)oWB.Sheets["32 M (2)"];
                            oSheet.Name = "BU19";
    
    
                            rowCount = 1;
                            foreach (DataRow dr in Rows)
                            {
                                rowCount += 1;
                                for (int i = 1; i < dt.Columns.Count + 1; i++)
                                {
                                    // Add the header the first time through 
                                    if (rowCount == 2)
                                    {
                                        oSheet.Cells[1, i + 115] = dt.Columns[i - 1].ColumnName;
                                    }
                                    oSheet.Cells[rowCount, i + 115] = dr[i - 1].ToString();
                                }
                            }
    
                            // Resize the columns 
                            oRange = oSheet.get_Range(oSheet.Cells[1, 115],
                                          oSheet.Cells[rowCount, dt.Columns.Count + 115]);
                            oRange.EntireColumn.AutoFit();
                        }
    
    
    
    
    
    
                        backgroundWorker1.ReportProgress(3);
                        //GU19
    
                        Rows = dt.Select("[Age Group] = 'GU19' AND [Tournament] = '" + tChoice + "'");
                     
    
    
      // Process repeated for GU19
    
                       backgroundWorker1.ReportProgress(4);
                        //GU19
    
                        Rows = dt.Select("[Age Group] = 'BU17' AND [Tournament] = '" + tChoice + "'");
                     
    
    
      // Process repeated for BU17
       
    
    //etc. for GU17, BU15, GU15, BU13, GU13, BU11, GU11
    
    
    
    
                        backgroundWorker1.ReportProgress(12);
    
                        oWB.SaveAs(FileName, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    
                        backgroundWorker1.ReportProgress(13);
    
                        if (MessageBox.Show("Do you wish to view the created tournament now?", "View Tournament", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            oXL.Visible = true;
    
                        }
                        else
                        {
                            //Save the sheet and close 
                            oSheet = null;
                            oRange = null;
                            oWB = null;
                            oWB.Close(Type.Missing, Type.Missing, Type.Missing);
                            oXL.Quit();
    
                            //Clean up 
                            //NOTE: When in release mode, this does the trick 
                            GC.WaitForPendingFinalizers();
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            GC.Collect();
                        }
    
                    
    
               
    
            }
    
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                // Change the value of the ProgressBar to the BackgroundWorker progress.
    
    
                Splash.ProgressBarValue = e.ProgressPercentage;
                 // Set the text.
               // Splash.lblLoading = e.ProgressPercentage.ToString();
            }
        }
    }
    That is everything on that form.
    The problem is right at the bottom referencing the problem. I have also tried not including that and instead placing what you initially stated into the main section of code instead of the
    Code:
    backgroundWorker1.ReportProgress(10);
    but that didn't seem to work either.

  8. #8
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: Updating Progress Bar on a separate form

    Well, your declaration and initialization of the variable Splash is local to the backgroundWorker1_DoWork eventhandler method. It can't be accessed by the backgroundWorker1_ProgressChanged eventhandler method since it's not in the correct scope. If you want to access the Splash variable, you need to declare it in the scope of the class.

    Code:
            private Form Splash;
    
            public CreateDraws()
            {
                InitializeComponent();
            }
    
            // etc...
    and initialize it and show it when the user clicks the btnCreateDraws button.

    Code:
                        if (DialogSave.ShowDialog() == DialogResult.OK)
                        {
                            MessageBox.Show("You selected the file: " + DialogSave.FileName);
    
                            this.Splash = new Splash();
                            this.Splash.Show();
                            backgroundWorker1.RunWorkerAsync(new string[] { tChoice.Text, BU19.Text, GU19.Text, BU17.Text, GU17.Text, BU15.Text, GU15.Text, BU13.Text, GU13.Text, BU11.Text, GU11.Text, DialogSave.FileName });
                        }
    Then run your background worker and update it by handling the BackgroundWorker.ProgressChanged event as you're doing now. I usually prefix references to class variables with the keyword "this" so I can recognize the scope more quickly.

    As for updating the progress bar on the Splash form, you will need to create a property in the Splash form code-behind itself that exposed the ProgressBar control. The easiest way would be to create a property like I had showed you earlier, then when you want to update the progress just call

    Code:
    this.Splash.ProgressBarValue = e.ProgressPercentage;
    Alternatively, you could create and initialize it in the BackgroundWorker.DoWork eventhandler method like you are now and then pass it as the userState argument to the BackgroundWorker.ReportProgress() method. Then in the BackgroundWorker.ProgressChanged eventhandler method, cast e.UserState to Splash and update it that way.

    Code:
    Splash splash = (Splash)e.UserState;
    splash.ProgressBarValue = e.ProgressPercentage;
    Also, if your ProgressChanged event for your BackgroundWorker isn't being fired, check and make sure that the BackgroundWorker.ReportsProgress property is set to "true" in the forms designer window. Although an exception would be thrown if you called the BackgroundWorker.ReportProgress() method and the BackgroundWorker.ReportsProgress property was set to false.
    Last edited by RaleTheBlade; February 15th, 2011 at 03:03 PM.
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

  9. #9
    Join Date
    Jan 2011
    Posts
    11

    Re: Updating Progress Bar on a separate form

    ok, that makes sense also however it still doesn't recognise the ProgressBarValue section in the splash form.
    but when I include the line
    Code:
    Splash splash = (Splash)e.UserState;
    It then recognises it but when the program runs it crashes with an error of

    not code but easier to view:

    Code:
    System.Reflection.TargetInvocationException was unhandled
      Message="Exception has been thrown by the target of an invocation."
      Source="mscorlib"
      StackTrace:
           at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
           at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
           at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
           at System.Delegate.DynamicInvokeImpl(Object[] args)
           at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
           at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
           at System.Threading.ExecutionContext.runTryCode(Object userData)
           at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
           at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(Form mainForm)
           at Tourny_Manager.Program.Main()
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
           at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
           at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
           at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
           at System.Activator.CreateInstance(ActivationContext activationContext)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: System.NullReferenceException
           Message="Object reference not set to an instance of an object."
           Source="Tourny Manager"
           StackTrace:
                at Tourny_Manager.CreateDraws.backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e)
                at System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e)
                at System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg)
           InnerException:

  10. #10
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: Updating Progress Bar on a separate form

    Did you create an instance of Splash in you DoWork eventhandler? And then did you pass that instance as an argument to the BackgroundWorker.ReportProgress() method? It should look something like this:

    Code:
    backgroundWorker1.ReportProgress(10, Splash);
    I think the way I had told you before would work the best and make the most sense. Declare Splash as a class field, then initialize it and show it before you call the backgroundWorker1.RunWorkerAsync() method. Then, you don't have to pass it has an argument to the ReportProgress method. You can just reference it in your ProgressChanged eventhandler.

    At the top of your class, add a field

    Code:
    private Splash splashForm;
    
    public CreateDraws()
    {
       InitializeComponent();
    }
    ...
    and in your btnCreateDraws_Click eventhandler method, initialize the form and show it before you call backgroundWorker1.RunWorkerAsync()

    Code:
    ...
    if (DialogSave.ShowDialog() == DialogResult.OK)
    {
       MessageBox.Show("You selected the file: " + DialogSave.FileName);
    
       this.splashForm = new Splash();
       this.splashForm.Show();
       backgroundWorker1.RunWorkerAsync(new string[] { tChoice.Text, BU19.Text, GU19.Text, BU17.Text, GU17.Text, BU15.Text, GU15.Text, BU13.Text, GU13.Text, BU11.Text, GU11.Text, DialogSave.FileName }); 
    }
    ...
    then in your ProgressChanged eventhandler

    Code:
    this.splashForm.ProgressBarValue = e.ProgressPercentage;
    And that should do the trick. It's a better design because it helps separate the UI functionality from the background data functionality.
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

  11. #11
    Join Date
    Jan 2011
    Posts
    11

    Re: Updating Progress Bar on a separate form

    Thank you so much!!! It now works!

    I took what you just gave me and it needed the
    Code:
    private Splash splashForm;
    which you just said instead of the previous
    Code:
    private Form Splash;
    It now recognises it and works properly. Also using what you've given me I've managed to solve it to update the text on the splash screen as well.

    Many thanks

  12. #12
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: [RESOLVED] Updating Progress Bar on a separate form

    You're welcome
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center