Click here to Skip to main content
Click here to Skip to main content

Progress Bar with a Twist

, 1 Aug 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Progress bar when number of steps can be estimated only roughly
Sample Image - still inside estimations

Sample Image - underestimations

Introduction

When we are dealing with a process which takes time to complete, we usually would like to have a progress bar showing progress of that process. In order to do this, we need to estimate the process.

The most relevant progress in most cases will be the progress expressed in time (seconds, minutes, hours, whatever). Arguable it's more natural for humans to watch something evolving in time than in bytes or some numbers.

But time is not a natural characteristic for most processes. Get, for example, copying a group of files, it's easy to express the progress in number of files or bytes. Try to do this in time – that would be impossible to do exactly, there are different factors that can affect the time, like file system cache, disk cache, distribution of files on a disk, what else is going on your computer, etc. The accurate estimation of time is possible only for processes which have speed and acceleration as natural characteristics.

Widespread implementations of a progress bar are fine when your estimation is accurate. But for situations when you cannot have an exact estimation in such cases, there is no way to cue a user that the estimations are not exact. Of course you can dynamically change the Maximum value when the progress bar approaches it but it still doesn't solve the problem with absence of any visual cue and it's not transparent for your user why suddenly the progress bar length has been changed (or even worse – the progress bar shows that it completed when clearly there is still something going on).

Background

One solution is to show some extra space in the control and let an indicator to overflow to that space once the current value exceeds the Maximum and as the indicator's length grows further to adjust that extra space. That will move the mark corresponding to Maximum to the left each time that adjustment happens, like in the pictures (bear in mind that the text on the indicator is optional and can be any).

So, for example, if you configure a progress bar with Minimum=0 and Maximum=100 then the overall length of the progress bar will be set to 125 (the default overflow step is 25%) with the cue set at 100 showing where is the expected maximum (in the control implementation I am using gradients and the cue is where the colour starts to change to red). As soon the value will reach 125 the overall length will be set to 150 and the Maximum mark will be moved to the left.

Using the Code

The control is no different to use than the standard XAML's ProgressBar because it inherits from the same RangeBase base class. The default length of the bar will be 125% of your range between Minimum and Maximum, but you can change it to any value you like. Just compile and reference from your project.

If you don't need this behaviour, you can set the OverflowStep = 0 in that case the control will behave the same way as the standard ProgressBar.

Below is the example how to use:

XAML

<Window 
	x:Class="ListViewEvaluation.ProgressBarTest"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:docactrl="clr-namespace:DocaLabs.Controls;assembly=DocaLabs.Controls"
	Title="ProgressBarTest" Height="100" Width="300">
	<Grid>
		<docactrl:OverflowProgressBar Height="20" Maximum="100" 
		VerticalAlignment="Center" Name="_overflowProgressBar2" 
		FontSize="12" />
    </Grid>
</Window>

C# Partial Class

public partial class ProgressBarTest : Window
{
    private System.Timers.Timer _timer;
    private delegate void ElapsedTimerInvokeDelegate();

    public ProgressBarTest()
    {
        InitializeComponent();

        _timer = new System.Timers.Timer(1000);
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
        _timer.Enabled = true;
    }

    void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        if (CheckAccess() == false)
                Dispatcher.Invoke(DispatcherPriority.Send, 
		new ElapsedTimerInvokeDelegate(OnTimerElapsed));
        else
            OnTimerElapsed();
    }

    void OnTimerElapsed()
    {
        _overflowProgressBar2.Value += 5;
        ((TextBlock)_overflowProgressBar2.Content).Text = 
		_overflowProgressBar2.Value + " of " + _overflowProgressBar2.Maximum;
    }
}

History

  • Modified introduction

License

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

Share

About the Author

Alexey Kadyrov
Architect
Ireland Ireland
No Biography provided

Comments and Discussions

 
Generalnice one PinmemberXmen W.K.3-Aug-09 7:29 
GeneralMy vote of 2 PinmemberJohnny J.31-Jul-09 11:50 
AnswerRe: My vote of 2 PinmemberAlexK123U1-Aug-09 1:42 
GeneralRead before you grade guys and gals - Pinmemberjbstinson31-Jul-09 9:30 
GeneralMy vote of 1 PinmemberKinStephen31-Jul-09 7:48 
Check your work
GeneralMy vote of 1 Pinmember-camalot-31-Jul-09 7:46 
GeneralMy vote of 1 PinmemberAcoustic31-Jul-09 6:19 
GeneralRe: My vote of 1 Pinmember-camalot-31-Jul-09 7:45 
GeneralRe: My vote of 1 PinmemberAlexey Kadyrov31-Jul-09 8:14 
GeneralRe: My vote of 1 PinmentorTrollslayer2-Aug-09 6:25 
GeneralRe: My vote of 1 PinmemberAlexK123U3-Aug-09 8:02 
GeneralRe: My vote of 1 PinmentorTrollslayer3-Aug-09 8:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141216.1 | Last Updated 1 Aug 2009
Article Copyright 2009 by Alexey Kadyrov
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid