65.9K
CodeProject is changing. Read more.
Home

ProgressBars for console apps

Aug 28, 2012

CPOL
viewsIcon

26440

downloadIcon

697

Progress bars for console apps

Introduction

It is nice to place progress bars in console apps, but sometimes there is no time to create them. So I wrote some utility classes to be used in all console apps.

About the code

The project has three classes; one abstract (AbstractBar) that define the generic behaviour of the progress bars and two implementation, which are: AnimatedBar and SwayBar. feel free to add your own implemetantion.

Abstract class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProgressBarDemo
{
    abstract class AbstractBar
    {
        public AbstractBar()
        {

        }

        /// <summary>
        /// Prints a simple message 
        /// </summary>
        /// <param name="msg">Message to print</param>
        public void PrintMessage(string msg)
        {
            Console.WriteLine(msg);
        }

        public abstract void Step();
    }
}

Animated class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProgressBarDemo
{
    class AnimatedBar : AbstractBar
    {
        List<string> animation;
        int counter;
        public AnimatedBar() : base()
        {
            this.animation = new List<string> { "/", "-", @"\", "|" };
            this.counter = 0;
        }

        /// <summary>
        /// prints the character found in the animation according to the current index
        /// </summary>
        public override void Step() {
            Console.Write(this.animation[this.counter]+"\b");
            this.counter++;
            if (this.counter == this.animation.Count)
                this.counter = 0;
        }
    }
}

Output:

Sway class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProgressBarDemo
{
    class SwayBar : AbstractBar
    {
        string bar;
        string pointer;
        string blankPointer;
        int counter;
        direction currdir;
        enum direction { right, left };
        public SwayBar() : base()
        {
            this.bar = "|                         |";
            this.pointer = "***";
            this.blankPointer = this.BlankPointer();
            this.currdir = direction.right;
            this.counter = 1;
        }

        /// <summary>
        /// sets the atribute blankPointer with a empty string the same length that the pointer
        /// </summary>
        /// <returns>A string filled with space characters</returns>
        private string BlankPointer() 
        {
            StringBuilder blank = new StringBuilder();
            for (int cont = 0; cont < this.pointer.Length; cont++)
                blank.Append(" ");
            return blank.ToString();
        }

        /// <summary>
        /// reset the bar to its original state
        /// </summary>
        private void ClearBar() 
        {
            this.bar = this.bar.Replace(this.pointer, this.blankPointer);    
        }

        /// <summary>
        /// remove the previous pointer and place it in a new possition
        /// </summary>
        /// <param name="start">start index</param>
        /// <param name="end">end index</param>
        private void PlacePointer(int start, int end) 
        {
            this.ClearBar();
            this.bar = this.bar.Remove(start, end);
            this.bar = this.bar.Insert(start, this.pointer);
        }

        /// <summary>
        /// prints the progress bar acorrding to pointers and current direction
        /// </summary>
        public override void Step()
        {
            if (this.currdir == direction.right)
            {
                this.PlacePointer(counter, this.pointer.Length);
                this.counter++;
                if (this.counter+this.pointer.Length == this.bar.Length)
                    this.currdir = direction.left;
            }
            else 
            {
                this.PlacePointer(counter - this.pointer.Length, this.pointer.Length);
                this.counter--;
                if (this.counter == this.pointer.Length)
                    this.currdir = direction.right;
            }
            Console.Write(this.bar + "\r");
        }
    }
}
Output:

Using the code  

In order to test our progress bars we are going to write a simple console app and write the following code in its program.cs file.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ProgressBarDemo
{
    class Program
    {
        static void Main()
        {
            AbstractBar bar;
            bar = new AnimatedBar();
            int wait = 100;
            int end = 50;

            //Animated bar
            Test(bar, wait, end);
            //Sway bar
            bar = new SwayBar();
            Test(bar, wait, end);
            Console.ReadLine();
        }

        public static void Test(AbstractBar bar, int wait, int end) 
        {
            bar.PrintMessage("Loading...");
            for (int cont = 0; cont < end; cont++)
            {
                bar.Step();
                Thread.Sleep(wait);
            }
            bar.PrintMessage("Finished");
        }
    }
}

Conclusion

I had fun writing those classes, I hope you find them useful.