Created
August 28, 2014 11:12
-
-
Save JanDeDobbeleer/cee85f62839687f47bda to your computer and use it in GitHub Desktop.
Circular Progress Bar (Silverlight)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<UserControl x:Name="userControl" x:Class="Foo.Bar.CircularProgressBar" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
mc:Ignorable="d" | |
FontFamily="{StaticResource PhoneFontFamilyNormal}" | |
FontSize="{StaticResource PhoneFontSizeNormal}" | |
Foreground="{StaticResource PhoneForegroundBrush}" | |
d:DesignHeight="480" d:DesignWidth="480"> | |
<Grid> | |
<Path x:Name="pathRoot" Stroke="{Binding SegmentColor, ElementName=userControl}" | |
StrokeThickness="{Binding StrokeThickness, ElementName=userControl}" HorizontalAlignment="Left" | |
VerticalAlignment="Top"> | |
<Path.Data> | |
<PathGeometry> | |
<PathGeometry.Figures> | |
<PathFigureCollection> | |
<PathFigure x:Name="pathFigure"> | |
<PathFigure.Segments> | |
<PathSegmentCollection> | |
<ArcSegment x:Name="arcSegment" SweepDirection="Clockwise" /> | |
</PathSegmentCollection> | |
</PathFigure.Segments> | |
</PathFigure> | |
</PathFigureCollection> | |
</PathGeometry.Figures> | |
</PathGeometry> | |
</Path.Data> | |
</Path> | |
</Grid> | |
</UserControl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Media; | |
namespace Fuo.Bar | |
{ | |
public partial class CircularProgressBar : UserControl | |
{ | |
public static readonly DependencyProperty PercentageProperty = | |
DependencyProperty.Register("Percentage", typeof (double), typeof (CircularProgressBar), new PropertyMetadata(65d, OnPercentageChanged)); | |
// Using a DependencyProperty as the backing store for StrokeThickness. This enables animation, styling, binding, etc... | |
public static readonly DependencyProperty StrokeThicknessProperty = | |
DependencyProperty.Register("StrokeThickness", typeof (int), typeof (CircularProgressBar), new PropertyMetadata(5)); | |
// Using a DependencyProperty as the backing store for SegmentColor. This enables animation, styling, binding, etc... | |
public static readonly DependencyProperty SegmentColorProperty = | |
DependencyProperty.Register("SegmentColor", typeof (Brush), typeof (CircularProgressBar), new PropertyMetadata(new SolidColorBrush(Colors.Yellow))); | |
// Using a DependencyProperty as the backing store for Radius. This enables animation, styling, binding, etc... | |
public static readonly DependencyProperty RadiusProperty = | |
DependencyProperty.Register("Radius", typeof (int), typeof (CircularProgressBar), new PropertyMetadata(25, OnPropertyChanged)); | |
// Using a DependencyProperty as the backing store for Angle. This enables animation, styling, binding, etc... | |
public static readonly DependencyProperty AngleProperty = | |
DependencyProperty.Register("Angle", typeof (double), typeof (CircularProgressBar), new PropertyMetadata(120d, OnPropertyChanged)); | |
public CircularProgressBar() | |
{ | |
InitializeComponent(); | |
Angle = (Percentage*360)/100; | |
RenderArc(); | |
} | |
public int Radius | |
{ | |
get { return (int) GetValue(RadiusProperty); } | |
set { SetValue(RadiusProperty, value); } | |
} | |
public Brush SegmentColor | |
{ | |
get { return (Brush) GetValue(SegmentColorProperty); } | |
set { SetValue(SegmentColorProperty, value); } | |
} | |
public int StrokeThickness | |
{ | |
get { return (int) GetValue(StrokeThicknessProperty); } | |
set { SetValue(StrokeThicknessProperty, value); } | |
} | |
public double Percentage | |
{ | |
get { return (double) GetValue(PercentageProperty); } | |
set { SetValue(PercentageProperty, value); } | |
} | |
public double Angle | |
{ | |
get { return (double) GetValue(AngleProperty); } | |
set { SetValue(AngleProperty, value); } | |
} | |
// Using a DependencyProperty as the backing store for Percentage. This enables animation, styling, binding, etc... | |
private static void OnPercentageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) | |
{ | |
var circle = sender as CircularProgressBar; | |
circle.Angle = (circle.Percentage*360)/100; | |
} | |
private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) | |
{ | |
var circle = sender as CircularProgressBar; | |
circle.RenderArc(); | |
} | |
public void RenderArc() | |
{ | |
var startPoint = new Point(Radius, 0); | |
Point endPoint = ComputeCartesianCoordinate(Angle, Radius); | |
endPoint.X += Radius; | |
endPoint.Y += Radius; | |
pathRoot.Width = Radius*2 + StrokeThickness; | |
pathRoot.Height = Radius*2 + StrokeThickness; | |
pathRoot.Margin = new Thickness(StrokeThickness, StrokeThickness, 0, 0); | |
bool largeArc = Angle > 180.0; | |
var outerArcSize = new Size(Radius, Radius); | |
pathFigure.StartPoint = startPoint; | |
if (startPoint.X == Math.Round(endPoint.X) && startPoint.Y == Math.Round(endPoint.Y)) | |
endPoint.X -= 0.01; | |
arcSegment.Point = endPoint; | |
arcSegment.Size = outerArcSize; | |
arcSegment.IsLargeArc = largeArc; | |
} | |
private Point ComputeCartesianCoordinate(double angle, double radius) | |
{ | |
// convert to radians | |
double angleRad = (Math.PI/180.0)*(angle - 90); | |
double x = radius*Math.Cos(angleRad); | |
double y = radius*Math.Sin(angleRad); | |
return new Point(x, y); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment