ProgressBars for console apps






4.23/5 (6 votes)
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.