
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 Canvas
es, a TextBox
and 12 Rectangle
s 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
{
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();
}
}