Web Design Nottingham Header

WPF Progress bar

Publication Date: Thu 10 Apr 2008
prog2.jpg

As part of the WPF project we are developing, it is a requirement for the application to communicate with a central server as part of the occassionally connected scenario.

The synchronisation process required a progress bar, in order to keep the user informed of the process.

We acheived this by creating a new XAML window and setting its border to none, in fact rather than me attempting to explain, here is the XAML:

<Window x:Class="MalachiCaseHandler.SynchProgress" xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml 
Title="SynchProgress" Height="80" Width="500" WindowStyle="None" ResizeMode="NoResize" ShowInTaskbar="False" WindowStartupLocation="CenterScreen">

<Grid Height="80" Width="500">
   
<ProgressBar Name="progressBar1" /> 
   <Viewbox Name="viewBox">
      
<TextBlock Name="textBlock" Text='Loading ...'/>
   
</Viewbox>
</Grid>
</
Window>

The XAML is very simple, you will notice the ViewBox we added to the window, this is to acheive text displayed on top of the progress bar.

The following resources show how the bar has been styled:

<LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1">
   
<GradientBrush.GradientStops>
   
<GradientStopCollection>
   
<GradientStop Color="#BBB" Offset="0.0"/>
   
<GradientStop Color="#EEE" Offset="0.1"/>
   
<GradientStop Color="#EEE" Offset="0.9"/>
   
<GradientStop Color="#FFF" Offset="1.0"/>
   
</GradientStopCollection>
   
</GradientBrush.GradientStops>
</LinearGradientBrush>

<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
<LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#AAA" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#CCC" Offset="0.0"/>
<GradientStop Color="#444" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid MinHeight="14" MinWidth="200">
<Border Name="PART_Track" CornerRadius="2" Background="{StaticResource PressedBrush}"
BorderBrush="{StaticResource SolidBorderBrush}" BorderThickness="1" />
<Border
Name="PART_Indicator"
CornerRadius="2"
Background="{StaticResource DarkBrush}"
BorderBrush="{StaticResource NormalBorderBrush}"
BorderThickness="1"
HorizontalAlignment="Left" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Once styled, we could now get on with updating the bar. This was done by utilising the Backgroundworker component. We setup the component in the constructor of the page:

worker = new BackgroundWorker();
worker.DoWork +=
new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged +=
new ProgressChangedEventHandler(worker_ProgressChanged);
worker.WorkerReportsProgress =
true;
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
this.progressBar1.Value = 0;
this.Cursor = Cursors.Wait;
worker.RunWorkerAsync();

We then coded the event handlers for the worker, the following is test code and has been replaced by our synchronisation code:

void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(4000);
worker.ReportProgress(i * 10);
}
}

Here is the code to update the progress and the text, notice we don't have to call invoke even though we are on a seperate thread to the UI, because we used the backgroundworker, it handles it for us.

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
this.textBlock.Text = e.ProgressPercentage.ToString() + "...";
}

Finally, we have the code for the synch completing:

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Cursor = Cursors.Arrow;
if (e.Error == null)
{
this.Close();
}
else
{
MessageBox.Show(e.Error.Message);
this.Close();
}
}

The example achieves a nice looking progress bar that enables you to provide a realistic view of the progress of a process. prog.jpg

Quotes

"Excellent service, at an affordable price. Thank you."
Sue Baxter (Director) - Internet Gardener

Latest Projects

Angel Wings web design Labarde web design Internet Gardener web design Stonesilver web design Build Investment Jewellery web design

Developer Certifications

MCPD logo

Partners

Comodo logo protx logo

Coding Standards

XHTML CSS

Agilis Software Limited | 2 Lynemouth Court, Arnold, Nottingham. NG5 8TY
Registered in England No. 5688723. VAT No. 886 4538 70
Tel: 07973 766989
Email: stephen@agilissoftware.co.uk