Click here to Skip to main content
11,492,523 members (60,942 online)
Click here to Skip to main content

WPF: Round Progress Bar

, 12 Jul 2009 CPOL 78.3K 4.7K 44
Rate this:
Please Sign up or sign in to vote.
One more way to create a round progress bar in WPF.

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)

Share

About the Author


Comments and Discussions

 
QuestionIts not working with asynchronous call [modified] Pin
Member 34620802-Mar-12 21:21
memberMember 34620802-Mar-12 21:21 
QuestionProgress not work! Pin
Ali_MH22-May-11 21:36
memberAli_MH22-May-11 21:36 
Generalweird progress bar shows up as top CPU drain on ANTS Profiler Pin
devvvy6-Mar-11 9:43
memberdevvvy6-Mar-11 9:43 
GeneralRe: weird progress bar shows up as top CPU drain on ANTS Profiler Pin
NeoPunk6-Mar-11 12:24
memberNeoPunk6-Mar-11 12:24 
GeneralMy vote of 5 Pin
kkirusha21-Nov-10 12:36
memberkkirusha21-Nov-10 12:36 
GeneralA good start... Pin
Josh Fischer11-Aug-09 8:53
memberJosh Fischer11-Aug-09 8:53 
GeneralRe: A good start... Pin
Kirill Kovalev14-Aug-09 20:22
memberKirill Kovalev14-Aug-09 20:22 
QuestionResize? Pin
DaProgramma25-Jul-09 3:40
memberDaProgramma25-Jul-09 3:40 
AnswerRe: Resize? Pin
Kirill Kovalev26-Jul-09 0:17
memberKirill Kovalev26-Jul-09 0:17 
QuestionArchive Size Pin
sotona12-Jul-09 5:16
membersotona12-Jul-09 5:16 
AnswerRe: Archive Size Pin
Kirill Kovalev12-Jul-09 7:54
memberKirill Kovalev12-Jul-09 7:54 

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.150520.1 | Last Updated 12 Jul 2009
Article Copyright 2009 by NeoPunk
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid