Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / WPF

WPF: Circular Progress Bar

Rate me:
Please Sign up or sign in to vote.
4.28/5 (23 votes)
22 Jun 2009CPOL 202.5K   59   33
Circular Progress bar in WPF

Ever wanted a slightly different progress bar from the standard WPF Progress bar which looks like the following (IsIndeterminate is like the WinForms Marquee enum value):

C#
1:  <ProgressBar VerticalAlignment="Top"
2:      Height="22" IsIndeterminate="True"/>

35288/image-thumb.png

What I would like is one that is more like the ones you see all over the web, where we have a round wheel sort of progress indicator. Would you like one of those?

Well fear not, your search is over, here is a very simple idea, just arrange some Ellipses in a circle within a Canvas and do a constant Rotate StoryBoard and bam, a circular progress bar.

Here is the XAML for such a UserControl.

XML
 1:  <UserControl x:Class="Sonic.CircularProgressBar"
 2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4:      Height="120" Width="120" Background="Transparent">
 5:      <Grid x:Name="LayoutRoot" Background="Transparent"
 6:            HorizontalAlignment="Center" VerticalAlignment="Center">
 7:          <Grid.RenderTransform>
 8:              <ScaleTransform x:Name="SpinnerScale"
 9:                              ScaleX="1.0" ScaleY="1.0" />
10:          </Grid.RenderTransform>
11:          <Canvas RenderTransformOrigin="0.5,0.5"
12:                  HorizontalAlignment="Center"
13:                  VerticalAlignment="Center"
14:                  Width="120" Height="120" >
15:              <Ellipse Width="21.835" Height="21.862"
16:                       Canvas.Left="20.1696"
17:                       Canvas.Top="9.76358"
18:                       Stretch="Fill" Fill="Orange"
19:                       Opacity="1.0"/>
20:              <Ellipse Width="21.835" Height="21.862"
21:                       Canvas.Left="2.86816"
22:                       Canvas.Top="29.9581" Stretch="Fill"
23:                       Fill="Black" Opacity="0.9"/>
24:              <Ellipse Width="21.835" Height="21.862"
25:                       Canvas.Left="5.03758e-006"
26:                       Canvas.Top="57.9341" Stretch="Fill"
27:                       Fill="Black" Opacity="0.8"/>
28:              <Ellipse Width="21.835" Height="21.862"
29:                       Canvas.Left="12.1203"
30:                       Canvas.Top="83.3163" Stretch="Fill"
31:                       Fill="Black" Opacity="0.7"/>
32:              <Ellipse Width="21.835" Height="21.862"
33:                       Canvas.Left="36.5459"
34:                       Canvas.Top="98.138" Stretch="Fill"
35:                       Fill="Black" Opacity="0.6"/>
36:              <Ellipse Width="21.835" Height="21.862"
37:                       Canvas.Left="64.6723"
38:                       Canvas.Top="96.8411" Stretch="Fill"
39:                       Fill="Black" Opacity="0.5"/>
40:              <Ellipse Width="21.835" Height="21.862"
41:                       Canvas.Left="87.6176"
42:                       Canvas.Top="81.2783" Stretch="Fill"
43:                       Fill="Black" Opacity="0.4"/>
44:              <Ellipse Width="21.835" Height="21.862"
45:                       Canvas.Left="98.165"
46:                       Canvas.Top="54.414" Stretch="Fill"
47:                       Fill="Black" Opacity="0.3"/>
48:              <Ellipse Width="21.835" Height="21.862"
49:                       Canvas.Left="92.9838"
50:                       Canvas.Top="26.9938" Stretch="Fill"
51:                       Fill="Black" Opacity="0.2"/>
52:              <Ellipse Width="21.835" Height="21.862"
53:                       Canvas.Left="47.2783"
54:                       Canvas.Top="0.5" Stretch="Fill"
55:                       Fill="Black" Opacity="0.1"/>
56:              <Canvas.RenderTransform>
57:                  <RotateTransform x:Name="SpinnerRotate"
58:                                   Angle="0" />
59:              </Canvas.RenderTransform>
60:              <Canvas.Triggers>
61:                  <EventTrigger RoutedEvent="ContentControl.Loaded">
62:                      <BeginStoryboard>
63:                          <Storyboard>
64:                              <DoubleAnimation
65:                                  Storyboard.TargetName
66:                                      ="SpinnerRotate"
67:                                   Storyboard.TargetProperty
68:                                      ="(RotateTransform.Angle)"
69:                                   From="0" To="360"
70:                                   Duration="0:0:01"
71:                                   RepeatBehavior="Forever" />
72:                          </Storyboard>
73:                      </BeginStoryboard>
74:                  </EventTrigger>
75:              </Canvas.Triggers>
76:          </Canvas>
77:      </Grid>
78:  </UserControl>

And here is all the C# codebehind:

C#
 1:  using System;
 2:  using System.Collections.Generic;
 3:  using System.Linq;
 4:  using System.Text;
 5:  using System.Windows;
 6:  using System.Windows.Controls;
 7:  using System.Windows.Data;
 8:  using System.Windows.Documents;
 9:  using System.Windows.Input;
10:  using System.Windows.Media;
11:  using System.Windows.Media.Animation;
12:  using System.Windows.Media.Imaging;
13:  using System.Windows.Navigation;
14:  using System.Windows.Shapes;
15:
16:  namespace Sonic
17:  {
18:      /// <summary>
19:      /// Provides a circular progress bar
20:      /// </summary>
21:      public partial class CircularProgressBar : UserControl
22:      {
23:          public CircularProgressBar()
24:          {
25:              InitializeComponent();
26:
27:              //Use a default Animation Framerate of 20, which uses less CPU time
28:              //than the standard 50 which you get out of the box
29:              Timeline.DesiredFrameRateProperty.OverrideMetadata(
30:                  typeof(Timeline),
31:                      new FrameworkPropertyMetadata { DefaultValue = 20 } );
32:          }
33:      }
34:  }

And here is an example of one of these CircularProgressBar controls in use:

XML
 1:  <Window
 2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4:          xmlns:local="clr-namespace:Sonic"
 5:      x:Class="Sonic.MainWindow">
 6:
 7:
 8:      <Grid>
 9:              <local:CircularProgressBar/>
10:          </Grid>
11:
12:  </Window>

And here it is in action (obviously, it looks better in run time)… Enjoy!

35288/image1.png

License

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


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
QuestionIts not working with asynchronous call Pin
Member 34620802-Mar-12 20:31
Member 34620802-Mar-12 20:31 
AnswerRe: Its not working with asynchronous call Pin
Sacha Barber2-Mar-12 23:43
Sacha Barber2-Mar-12 23:43 
QuestionDoesn't appear when toggling visibility property. Pin
hopmedic15-Dec-11 9:59
hopmedic15-Dec-11 9:59 
AnswerRe: Doesn't appear when toggling visibility property. Pin
Sacha Barber15-Dec-11 20:14
Sacha Barber15-Dec-11 20:14 
GeneralBug if used in multiple occasion. Pin
ernii23-Jun-10 0:48
ernii23-Jun-10 0:48 
GeneralRe: Bug if used in multiple occasion. Pin
Sacha Barber29-Jun-10 4:37
Sacha Barber29-Jun-10 4:37 
GeneralUse RadialPanel for layout Pin
Christian Andritzky10-Jun-10 4:41
Christian Andritzky10-Jun-10 4:41 
GeneralRe: Use RadialPanel for layout Pin
Sacha Barber10-Jun-10 5:39
Sacha Barber10-Jun-10 5:39 
GeneralRe: Use RadialPanel for layout Pin
Christian Andritzky10-Jun-10 6:24
Christian Andritzky10-Jun-10 6:24 
GeneralRe: Use RadialPanel for layout Pin
Sacha Barber10-Jun-10 6:25
Sacha Barber10-Jun-10 6:25 
JokeResizing Pin
Tinkering Turtle18-Sep-09 11:25
Tinkering Turtle18-Sep-09 11:25 
GeneralRe: Resizing Pin
Sacha Barber18-Sep-09 19:42
Sacha Barber18-Sep-09 19:42 
GeneralUsing the circular ProgressBar in a Multithreaded environment Pin
JNongrum31-Aug-09 2:21
JNongrum31-Aug-09 2:21 
GeneralNice but misleading title. Pin
Ali Rafiee24-Jul-09 10:26
Ali Rafiee24-Jul-09 10:26 
General[My vote of 2] WPF = lookless controls & templates Pin
mfrasiu30-Jun-09 10:41
mfrasiu30-Jun-09 10:41 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
Sacha Barber30-Jun-09 21:35
Sacha Barber30-Jun-09 21:35 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
mfrasiu2-Jul-09 11:00
mfrasiu2-Jul-09 11:00 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
Sacha Barber2-Jul-09 21:47
Sacha Barber2-Jul-09 21:47 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
mfrasiu3-Jul-09 9:49
mfrasiu3-Jul-09 9:49 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
Sacha Barber3-Jul-09 21:24
Sacha Barber3-Jul-09 21:24 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
Delfofthebla17-Mar-15 12:59
Delfofthebla17-Mar-15 12:59 
GeneralRe: [My vote of 2] WPF = lookless controls & templates Pin
Sacha Barber17-Mar-15 14:13
Sacha Barber17-Mar-15 14:13 
GeneralNice Pin
Bishoy Demian30-Jun-09 10:03
Bishoy Demian30-Jun-09 10:03 
GeneralRe: Nice Pin
Sacha Barber30-Jun-09 21:36
Sacha Barber30-Jun-09 21:36 
GeneralNice Pin
Bishoy Demian30-Jun-09 10:02
Bishoy Demian30-Jun-09 10:02 

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.