Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / CSS

An External or Standalone ProgressBar

0.00/5 (No votes)
11 Nov 2012CPOL7 min read 19K   748  
Create a simple, flexible, standalone ProgressBar that can be added to any class with relative ease.

Download source files

Download demo project

Image 1 

Introduction 

This article came into being because of a long and frustrating search into what I thought was a simple thing to find.  But doesn't it always start off that way?  All I wanted was a simple way to add a standalone ProgressBar to a particular class that runs a process of varying, and sometimes lengthy times.  Could not use the ProgressBar in the Windows Form ToolBox and get a good result.  I would have had to code most of the project in the Main Form and that's just wrong on so many levels.

Searched for quite a while and found an excellent article that offered a possible solution.  The article is entitled: "Dealing with Progressive Operations" by _Erik_.  It had the solution I was looking for, but way too complicated for the simple project I was working on.  Needed something less cumbersome, and yes probably not entirely OOP as I didn't want to get involved in interfaces.  The code in his article is great for larger, more complex projects, just not this tiny one.  It would have looked very lopsided as a huge part of the total code of the project would have dealt with the "simple issue" of generating a ProgressBar in a class that is not a part of the Main Form. 

Just a quick side note: I plan on using the contents of Erik's article on larger scale projects as it is ideal for such.

The Problem to Solve 

Create a simple, flexible, standalone ProgressBar that can be added to any class with relative ease.

Overview 

I've attempted to make this as much of a plug-and-play type project as I could.   After all, that is really what I was looking for in the first place.  So, I've set it up with the six files that make it work.  If you like, you can skip to the end of this article and just try following the directions for inserting the StandAloneProgressBar into your project.  I've tried it on a couple of different projects just to make sure the directions work.  Of course I can't visualize every variance, so I'm counting on you to make any necessary adjustments to the code you require.   If you think of any changes I can make to this article that will make it better, please let me know.  By the way, you can make it even more complex by adding a second ProgressBar control and more Labels.

I've included a tiny demo project that doesn't do anything more than go to three Websites and access their RSS Feed Page lists.   I added the StandAloneProgressBar Form to the project to display a ProgressBar while the program is accessing the different sites.  In my demo, I visit three different sites because my PC and connection are so fast that I could never see the ProgressBar for more than a couple of seconds, otherwise one website would have been more than enough.  By the way, the demo includes a really useful example of Linq to XML, if you are interested in that subject. 

Basically, this comes down to adding the Form for the StandAloneProgressBar and inserting the contents of three text files into the proper places in your project.

Using the Code  

File descriptions   

  • StandAloneProgressBar.cs - Windows Form class that is the ProgressBar to be used by other classes.  Of course it includes the two attendant files:  
    • StandAloneProgressBar.Designer.cs
    • StandAloneProgressBar.resx
  • Property and Event Declarations.txt - contains the text add-ins for the Public Properties and Event Declarations.
  • InitialValues.txt - Contains all the needed variable initializers and calls the start event for our ProgressBar.
  • StartTheProgressBar.txt - Instantiates our ProgressBar and makes the call to it.

StandAloneProgressBar.cs 

This is the Windows Form class that we will be calling from within our current application.  The image of it is at the beginning of this article. It is a very simple form consisting of two Labels and a ProgressBar control.  That's all there is to the form.

The code that follows is all we need to make the events work.   This contains the actual code of the three events that we declared in the class that will be using the StandAloneProgressBar. Eric really did a sublime job.

C#
public partial class StandAloneProgressBar : Form
    {
        public StandAloneProgressBar()
        {
            InitializeComponent();
 
            // Instantiate the class the StandAloneProgressBar is in so we can call its Methods 
            // and use its Public Properties and Events.
            RSSFeed myDemo = new RSSFeed();
 
            // This Event, we defined in the class RSSFeed, displays the properly
            // initialized ProgressBar with these values.
            myDemo.OperationStart += (sender, e) =>
                {
                    lblMainTitle.Text = myDemo.MainTitle;   // Updates the text for lblMainTitle.
                    lblSubTitle.Text = myDemo.SubTitle;     //  Updates the text for lblSubTitle.
                    pgbMainBar.Maximum = myDemo.TotalSteps;     // Divides the ProgressBar up into 
                                                                    // the number of TotalSteps.
                    pgbMainBar.Value = myDemo.CurrentProgress;   // This sets the "step" 
                                                                     // the ProgressBar draws.

                    Refresh();  // Forces the control to redraw itself.
                };
 
            // This Event, we defined in RSSFeed, is just updating the "step" of the ProgressBar.
            myDemo.OperationProgress += (sender, e) =>
                {
                    lblSubTitle.Text = "Visiting the RSS Feed page for " + myDemo.SubTitle;
                    pgbMainBar.Value = myDemo.CurrentProgress;  //  This sets the "step" 
                                                                    // the ProgressBar draws.

		  // Processes all Windows messages currently in the message queue.
                    Application.DoEvents();
                };
 
            // This Event, we defined in RSSFeed, terminates the ProgressBar.
            myDemo.OperationEnd += (sender, e) => Close();
 
            // Subscribe to the Shown event of the Form.
            // This actually calls the method in RSSFeed that we want the ProgressBar to show up for.
            Shown += (sender, e) => myDemo.GetRSSFeed();
 
        } // end method StandAloneProgressBar

    } // end class StandAloneProgressBar

Property and Event Declarations.txt 

This Text file contains all the Public Properties and Event Declarations. Of special interest is the Public Property CurrentProgress.  It's written this way so as to allow flexibility in the code of the calling class without the hassle of editing it every time you use it in new class.

C#
#region Public Properties
        
        public string MainTitle { get; set; }  // Will be the text placed in lblMainTitle
        public string SubTitle { get; set; }   // Will be the text placed in lblSubTitle
                
        public int TotalSteps { get; set; }    // This is how many times the operation is performed.
					          // Divides the ProgressBar into equal segments of 
                                                  // this percentage size.
        public int CurrentStep { get; set; }  // Tracks current position of the ProgressBar.

        public int CurrentProgress            // This calculates the new current position of 
                                                 // the ProgressBar .
        {
            get
            {
                int ret = 0;
 
                if (TotalSteps > 0)
                {
                    double currentStep = CurrentStep;
                    double totalSteps = TotalSteps;
                                        
                    ret = Convert.ToInt32((currentStep / totalSteps) * totalSteps);
                }
 
                return ret;
            }
        }
 
        #endregion
                
        #region Define the Events
 
        // Shows the ProgressBar with the proper initial values.
        protected void OnOperationStart(EventArgs e)
        {
            if (OperationStart != null)
                OperationStart(this, e);
        }
 
        // Updates the bar position itself.
        protected void OnOperationProgress(EventArgs e)
        {
            if (OperationProgress != null)
                OperationProgress(this, e);
        }
 
        // Terminates the ProgressBar.
        protected void OnOperationEnd(EventArgs e)
        {
            if (OperationEnd != null)
                OperationEnd(this, e);
        }
 
        #endregion
 
        #region Declare the Events
 
        public event EventHandler OperationStart;   
        public event EventHandler OperationProgress; 
        public event EventHandler OperationEnd; 
 
        #endregion

StartTheProgressBar.txt  

This Text file has just a couple of lines of code that must replace the current call to the class using the StandAloneProgessBar.   As you can see from below, I've actually captured the entire instance of the old call being commented out and replaced by the two new lines of code.

Note the final line of code: sp.ShowDialog();.   It is referring to the last line of code in StandAloneProgressBar.cs.   That is the line where you substitute in the actual call to your method that uses the StandAloneProgressBar. (See step 8 below)

C#
// Use this event to trigger the whole thing.
    private void button1_Click(object sender, EventArgs e)
    {

        //// Instantiates the class.  Allows us to make a call to our procedure.
        //RSSFeed myRSS = new RSSFeed();

        //// Calls the procedure we want to execute.
        //myRSS.GetRSSFeed();

        // Instantiate the ProgressBar object.
        StandAloneProgressBar sp = new StandAloneProgressBar();

        // This will bring up a blank invisible ProgressBar,
        // but it starts the whole process in StandAloneProgressBar.
        sp.ShowDialog();
    }

InitialValues.txt 

These four variables are the values the our version of the ProgressBar need in order to work.  Please change the variable TotalSteps!  I am somewhat embarrassed to admit that I failed to follow this instruction when testing the demo.  Right after the initializations is the line that calls the Start Event of the StandAloneProgressBar.   I placed it there to eliminate the chance of missing a needed function call.

C#
// Set initial values
    TotalSteps = 10;    // You need to CHANGE THIS to what you need.  Preferably a variable.
    CurrentStep = 0;
    MainTitle = "Testing the ProgressBar";
    SubTitle = "";

    // Show the ProgressBar with its initial conditions.
    OnOperationStart(EventArgs.Empty);

Step by Step Instructions to Insert the StandAloneProgressBar into a Project

      1)  Copy all three StandAloneProgressBar files and the three Text files to your current working directory.
      2)  Right-click on the project name in the Solution Explorer window and choose "Add Existing Item…"
        Select all the files you Want to copy and hit Okay.
      3)  Edit the class you need our ProgressBar to work in.
        Copy all the text contained in the textfile Property and Event Declarations.txt into the beginning of the class you need our ProgressBar to work in.
      4)  Edit StandAloneProgressBar.cs code.
        Refactor the namespace to your current project's namespace. 
        Find and Replace: the name of the class that needs to use this ProgressBar, (on or near line 20).
          Recommend refactoring the name of myDemo to something more pertinent for your project.
      5)  Copy the contents of InitialValues.txt to the beginning of the method that uses this ProgressBar.
        This also, contains the call to initialize our ProgressBar.
        Change the Public Property TotalSteps to what your correct count is to be. NOTE: This should be a variable.
        Change the Public Properties MainTitle and SubTitle to your desired text.
      6)  Add the three lines of code that update the progress of our ProgressBar to an appropriate place in the repeating process:
        SubTitle = "(name you want displayed on the SubTitle, or not)";
        CurrentStep++;
        OnOperationProgress(EventArgs.Empty);
      7)  Add these two lines of code to the end of the method using our ProgressBar. This terminates it.
        // Operation is completed, terminate the ProgressBar.
        OnOperationEnd(EventArgs.Empty);
      8)  In StandAloneProgressBar.cs, at the very end of the code (line 47) that starts with the Shown Event of the Form, change the name of the called method from mydemo.GetRSSFeed() to the method that uses it. In this case of the included demo, it is myDemo.GetRSSFeed().
      9)  Comment out the current call to the method using our ProgressBar and copy the contents of StartTheProgressBar.txt under it. These two lines of code will replace the call.
      10) You are ready to try it out.

Points of Interest

This was an interesting challenge in that I  had to take Erik's sublime code, setup for use as an interface and work through it to deterrmine its core essence.   I learned a lot about this code by reverse engineering it.  Also, just want to mention one more time that the demo program has really nice examples of Linq to XML code for extracting RSS Feed page data.   It resides in the RSSFeed.cs file.

History   

Final draft submitted 11/11/12. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)