UPDATE December 30, 2015: I made a new and improved version of the progress ring control. The code is not shown below – that is older code – but you can get a complete Visual Studio project by downloading this zip file: http://www.rectorsquid.com/CircleprogressRing.zip
Here’s a picture of the control used three times in the main windows with three different sizes, line widths, and colors:
END-OF-UPDATE
Although Microsoft provides a nice progress bar with both determinate and indeterminate displays, as well as a nice spinning circle progress ring, there doesn’t seem to be a determinate progress ring of any sort.
I found various ways to draw a progress ring that shows overall progress (not spinning dots). one method used a dashed line for an ellipse and then changed the dash-to-gap values to change the progress. Actually, it changed just the dash length since the gap length was set to some huge number. I then decided that I wanted a storyboard animation to do the "drawing" because it would be smoother. At least I imagined that it would be smoother. But the dash length of a dashed line cannot be controlled with a storyboard animation. So I switched to using the ArcSegment element instead of an ellipse. The ArcSegment is hard to work with, especially with the issue of having to tell the arc if it is large or small. The IslargeArc attribute seems a bit odd because the endpoint of the arc could easily make it clear to the ArcSegment what to do, but then I am assuming that everyone wants their arc to fit within the size specified. Overall, it’s hard to work with because of this, and I’ll explain more later.
Here is the code for the main page of a sample app. Using Visual Studio, create a blank page project for the store. Then just cut and paste this code in the two mainpage files mentioned here:
The mainpage.xaml.cs code starts a timer for demonstration purposes. this is not needed for anything but this example. The code just continuously sets the bar length.
lately, I’ve been using numbers between 0 and 1 for things like progress reporting. This seems better than using 0 to 100, and the value needs to be a floating point number anyhow. It would be easy to change this to 0 to 100.0, but would then require at least one or two more lines of code, or an extra value in a few equations.
The code for the round progress bar is simple. The xaml file contains just enough information to create the ArcSegment. Change this to the sizes, colors, etc., that suit your purposes. I was only interested in this size, and it’s good enough to get anyone started when they make their own.
The .cs file below is a simple as the xaml file. There is a single interesting method in the class for setting the bar length. This takes a number from 0 to 1.0 (inclusive) and then changes the end point to the proper location.
I mentioned the storyboard animation before. The code is still present, but it’s actually not al that good at animating the arc. If the storyboard is started after the IslargeArc attribute is set, there is a slight change in the shape of the arc when it goes from less than 180 to greater than 180 degrees of arc. The glitch that is visible will depend a lot on how big of a change is taking place, and small changes don’t show much glitch at all. it might be better to change IsLargeArc after the storyboard is started, but there can still be a minimal delay between the change and the animation.
I ended up opting to change the point and the IsLargeArc value at the same time. The animation is very smooth on my Windows 8.1 laptop. Note than the code to change a UI element must be run on the UI thread, so the dispatcher is used to accomplish this.
That’s it. A nice simple round progress bar for anyone to use.
Thank You very much Dave, but i want to increase the size of circular progress bar can u please give me the points and size values.
I have tried many values but i am not getting the perfect circular ring.
Ok, I hate writing code for other people, especially when it looks really easy to me. But since this is the giving time of year, here is a Visual Studio project that has a progress ring control that you can use as-is at any size, with any line width, and in any color. You can look at the very few lines of code that alter the dimensions to see why your previous attempts failed.
http://www.rectorsquid.com/CircleprogressRing.zip
Note that the values in the xaml file for the size are all changed in the C# code so you can probably just ignore them when trying to see what was wrong. The function that is important is shown here:
private void UpdateSizing()
{
ThePath.Stroke = Color;
ThePath.StrokeThickness = LineWidth;
TheGrid.Width = Size;
TheGrid.Height = Size;
ThePathFigure.StartPoint = new Point( HalfInsideSize, InsideSize );
TheSegment.Size = new Windows.Foundation.Size( HalfInsideSize, HalfInsideSize );
SetBarLength( ProgressValue );
}
The Size, InsideSize, and HalfInsideSize variables all come from the specified size value and get adjusted to account for the LineWidth. You can see that the grid element must be sized bigger than the ring because the circle we are drawing is the center of the stroke and the stroke therefore goes outside of the circle. The StartPoint is always at the bottom and halfway across the container grid. And of course, the size of the segment is specified as half of the circle for some reason – maybe because it is a radius, not a diameter!
I compiled and tested this with Visual Studio 2015 on Windows 10. If it doesn’t work for you, send me a screenshot and a copy of ALL of your code.
Dave
Here’s what to change to make this start at the top. Note that this might not be the best way to do this, but it worked and was easy for me to figure out:
That should do it. You should be able to see why some of these changes are pretty obvious. It’s the large arc change that is the one that would screw up most people. Notice that the large arc value is set to ‘true’ when the length of the arc goes past 180 degrees. So you change the start point and then subtract 180 degrees worth of arc from the angle calculation and then just… I don’t know, change the large arc setting. It’s not totally clear to me hwy my change makes sense, but it works.
Hi Dave,
1. I want to change the start position of the progress bar to top of the circle
2. Two i need to make make the path of the circular bar with gray color untill the progress bar reaches it and overwrites with black.
I am very new to UWP (XAML)
tried to work around the code but sadly i could not figure it out.
Please could you help me out ..!
Also I need to adapt the progress bar based on width and height
Hi.
I found this article very helpful, but I wish you could tell a little bit more about the logic used to control the ring.
For example, I was trying to adapt this piece of code, but I need a bigger StrokeThickness (let’s imagine I want the circle filled to the center). Adjusting the StrokeThickness by itself won’t do it because the control will start to go out of bounds. How can I adjust the code to manage what I want? Can you help me?
Thanks.
It’s been a while since I looked at that code. But if I remember correctly, the ArcSegment size needs to be smaller if you make the stroke thickness bigger. You also need to change the start point so that it is on that radius.