Click here to Skip to main content
15,885,767 members
Articles / Desktop Programming / WPF

Progress Bar with a Twist

Rate me:
Please Sign up or sign in to vote.
3.06/5 (8 votes)
1 Aug 2009CPOL3 min read 41.7K   617   17   14
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

XML
<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

C#
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)


Written By
Architect
Ireland Ireland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow to put it into my C# Toolbox? Pin
Member 1164799917-Aug-15 22:46
Member 1164799917-Aug-15 22:46 
Generalnice one Pin
Xmen Real 3-Aug-09 6:29
professional Xmen Real 3-Aug-09 6:29 
GeneralMy vote of 2 Pin
Johnny J.31-Jul-09 10:50
professionalJohnny J.31-Jul-09 10:50 
AnswerRe: My vote of 2 Pin
Alexey Kadyrov1-Aug-09 0:42
Alexey Kadyrov1-Aug-09 0:42 
GeneralRead before you grade guys and gals - Pin
jbstinson31-Jul-09 8:30
jbstinson31-Jul-09 8:30 
GeneralMy vote of 1 Pin
Stephen Brannan31-Jul-09 6:48
Stephen Brannan31-Jul-09 6:48 
Check your work
GeneralMy vote of 1 Pin
ryanconrad31-Jul-09 6:46
ryanconrad31-Jul-09 6:46 
GeneralMy vote of 1 Pin
TylerBrinks31-Jul-09 5:19
TylerBrinks31-Jul-09 5:19 
GeneralRe: My vote of 1 Pin
ryanconrad31-Jul-09 6:45
ryanconrad31-Jul-09 6:45 
GeneralRe: My vote of 1 Pin
Alexey Kadyrov31-Jul-09 7:14
Alexey Kadyrov31-Jul-09 7:14 
GeneralRe: My vote of 1 Pin
Trollslayer2-Aug-09 5:25
mentorTrollslayer2-Aug-09 5:25 
GeneralRe: My vote of 1 Pin
Alexey Kadyrov3-Aug-09 7:02
Alexey Kadyrov3-Aug-09 7:02 
GeneralRe: My vote of 1 Pin
Trollslayer3-Aug-09 7:26
mentorTrollslayer3-Aug-09 7:26 

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

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