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:
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.