Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF: Round Progress Bar

0.00/5 (No votes)
12 Jul 2009 1  
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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here