Click here to Skip to main content
Licence CPOL
First Posted 12 Jul 2009
Views 44,128
Downloads 1,655
Bookmarked 35 times

WPF: Round Progress Bar

By NeoPunk | 12 Jul 2009
One more way to create a round progress bar in WPF.

1

2
2 votes, 33.3%
3

4
4 votes, 66.7%
5
4.00/5 - 6 votes
μ 4.00, σa 1.81 [?]

Introduction

The standard WPF progress bar is very boring, and doesn't allows lot of customizations. I created a round progress bar like the ones that I always see in the web and in Flash applications.

Here is the simple idea of how to implement such a control. I used two Canvases, a TextBox and 12 Rectangles to create the progress bar.

Here is the XAML code of the UserControl:

<UserControl x:Class="RounderProgressBar.RounderProgressBarControl"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml 
    Height="400" Width="400">

    <UserControl.Resources>  
        <Style x:Key="canvasStyle" TargetType="{x:Type Canvas}"> 
            <Setter Property="Background" Value="Transparent"/> 
        </Style>  
        <Style x:Key ="rectangle" 
                     TargetType="{x:Type Rectangle}"> 
            <Setter Property="Width" Value="35"/> 
            <Setter Property="Height" Value="100"/> 
            <Setter Property="Fill" Value="LightBlue"/> 
            <Setter Property="Canvas.Left" Value="190"/> 
            <Setter Property="Canvas.Top" Value="0"/> 
            <Setter Property="RadiusX" Value="10"/> 
            <Setter Property="RadiusY" Value="10"/> 
        </Style> 
        <Style x:Key="percents" TargetType="{x:Type TextBox}">
            <Setter Property="FontSize" Value="20" />
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="IsReadOnly" Value="true"/>
        </Style>      
    </UserControl.Resources> 

    <Canvas RenderTransformOrigin="0.5,0.5" 
             Style="{StaticResource canvasStyle}"> 
        <TextBox Name="tbPercents" 
          Style="{StaticResource percents}"  
          Canvas.Left="172" Canvas.Top="189" 
          TextChanged="tblPercents_TextChanged"> 
            100% 
        </TextBox>         
        <Canvas Name="rotationCanvas" 
               RenderTransformOrigin="0.5,0.5" 
               Style="{StaticResource canvasStyle}"> 
            <Rectangle  Style="{StaticResource rectangle}"> 
            </Rectangle> 
            <Rectangle Opacity="0.92" 
                    Style="{StaticResource rectangle}"> 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="30" 
                            CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.84" 
                    Style="{StaticResource rectangle}"> 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="60" 
                           CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.76" 
                     Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="90" 
                          CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.66" 
                   Style="{StaticResource rectangle}"> 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="120" 
                         CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.58" 
                      Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="150" 
                           CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.5" 
                      Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="180" 
                          CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.42" 
                    Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="210" 
                      CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.34" 
                      Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="240" 
                      CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.26" 
                  Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="270" 
                      CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.16" 
                 Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="300" 
                      CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Rectangle Opacity="0.08" 
                   Style="{StaticResource rectangle}" > 
                <Rectangle.RenderTransform> 
                    <RotateTransform Angle="330" 
                       CenterX="10" CenterY="200"/> 
                </Rectangle.RenderTransform> 
            </Rectangle> 
            <Canvas.RenderTransform> 
                <RotateTransform x:Name="SpinnerRotate"  
                   Angle="0" CenterX="200" 
                   CenterY="200" /> 
            </Canvas.RenderTransform> 
        </Canvas> 
    </Canvas> 
</UserControl>

To add some animation to the progress bar, I use a System.Timer and rotate the second Canvas on 30 angles every 100 milliseconds.

Here is the code in С#:

using System.Timers; 
using System.Windows; 
using System.Windows.Controls;

namespace RounderProgressBar 
{ 
    /// <summary> 
    /// Interaction logic for RounderProgressBar.xaml 
    /// </summary> 
    public partial class RounderProgressBarControl : UserControl 
    { 
        private const string PERCENTS_TEXT = "{0}%"; 
        private delegate void VoidDelegete(); 
        private Timer timer; 
        private bool loaded; 
        private int progress; 

        public RounderProgressBarControl() 
        { 
            InitializeComponent(); 
            Loaded += OnLoaded; 
        }

        void OnLoaded(object sender, RoutedEventArgs e) 
        { 
            timer = new Timer(100); 
            timer.Elapsed += OnTimerElapsed; 
            timer.Start(); 
            loaded = true; 
        }

        void OnTimerElapsed(object sender, ElapsedEventArgs e) 
        { 
            rotationCanvas.Dispatcher.Invoke 
            ( 
                new VoidDelegete( 
                    delegate 
                        { 
                            SpinnerRotate.Angle += 30; 
                            if (SpinnerRotate.Angle == 360) 
                            { 
                                SpinnerRotate.Angle = 0; 
                            } 
                        } 
                    ), 
                null 
            );  
        }

        private void tblPercents_TextChanged(object sender, 
                     TextChangedEventArgs e) 
        { 
            if (loaded) 
            { 
                Canvas.SetLeft(tbPercents, 
                  (rotationCanvas.ActualHeight - tbPercents.ActualWidth) / 2); 
                Canvas.SetTop(tbPercents, 
                  (rotationCanvas.ActualHeight - tbPercents.ActualHeight) / 2);    
            } 
        } 

        private void UpdateProgress() 
        { 
            tbPercents.Text = string.Format(PERCENTS_TEXT, progress); 
        } 

        public int Progress 
        { 
            get { return progress; } 
            set 
            { 
                progress = value; 
                UpdateProgress(); 
            } 
        } 
    } 
}

You can easily change the percentage info on the progress bar using the Progress property.

public int Progress 
{  
    get { return progress; } 

    set 
    { 
        progress = value; 
        UpdateProgress(); 
    }  
}

License

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

About the Author

NeoPunk



Belarus Belarus

Member


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionProgress not work! PinmemberAli_MH21:36 22 May '11  
Generalweird progress bar shows up as top CPU drain on ANTS Profiler Pinmemberdevvvy9:43 6 Mar '11  
GeneralRe: weird progress bar shows up as top CPU drain on ANTS Profiler PinmemberNeoPunk12:24 6 Mar '11  
GeneralMy vote of 5 Pinmemberkkirusha12:36 21 Nov '10  
GeneralA good start... PinmemberJosh Fischer8:53 11 Aug '09  
GeneralRe: A good start... PinmemberKirill Kovalev20:22 14 Aug '09  
QuestionResize? PinmemberDaProgramma3:40 25 Jul '09  
AnswerRe: Resize? PinmemberKirill Kovalev0:17 26 Jul '09  
QuestionArchive Size Pinmembersotona5:16 12 Jul '09  
AnswerRe: Archive Size PinmemberKirill Kovalev7:54 12 Jul '09  

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.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120210.1 | Last Updated 12 Jul 2009
Article Copyright 2009 by NeoPunk
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid