This short article presents a control, named Win8ProgressRing, that mimics the
Windows 8 Progress Ring.
Only a brief discussion of its implementation will be provided. In the following
discussions, properties that are specified by the developer are displayed in
BoldMixedCase text. Variables, used internally
by the software are displayed in italicized_lowercase
Table of Contents
returns the reader to the top of the Table of Contents.
The Win8ProgressRing control has two properties that form the user's visual image.
In the figure to the right, the control's boundary is drawn in
The developer specifies the control's top-left corner by dragging the control
from the ToolBox to a position on the form. This position becomes ( 0, 0 ) in the
control's graphic environment. The developer specifies the
control_height by either dragging the control's
resizing handles or by specifying the Control_Height
property. The control_width is set equal
to the control_height.
The indicator color defaults to white. To change the indicator color, the developer
specifies the new color through the Indicator_Color
The control's background color is transparent and cannot be changed.
The Win8ProgressRing control has the following properties available to the developer:
||Gets or sets a value indicating whether the control rotates the indicators
automatically. If true, the control
animates the indicator rotation; if false,
the control moves the indicators only when the Pulse method is invoked.
The default value is true.
||Gets or sets the height of the control. When changed, this property
also causes other internal values for the control to be changed. The default
value is 100 pixels.
void adjust_control_dimensions_from_height ( int new_height )
indicator_radius = round ( ( double ) new_height /
( double ) SIZE_FACTOR );
indicator_diameter = 2 * indicator_radius;
control_height = SIZE_FACTOR * indicator_radius;
control_width = control_height;
outer_radius = control_height / 2;
inner_radius = outer_radius - indicator_diameter;
indicator_center_radius = inner_radius +
this.Height = control_height;
this.Width = control_width;
||Gets or sets the color of the indicators in the Win8ProgressRing control.
The default value is Color.White.
||The time, in milliseconds, between movements of the indicators. The
value must be greater than or equal to ten, and less than or equal to 200.
The default is 100 milliseconds.
The Pulse method is used to rotate the indicators once each time it is invoked.
Its signature is:
public void Pulse ( )
The Win8ProgressRing control is a
Control. Parts of the control are drawn when the control's
OnPaint method is invoked.
The control's graphic is made up of two distinct graphic images: the background
graphic and the indicator graphic.
Once drawn, the background graphic does not need to be redrawn unless
Control_Height is changed. The indicator
graphic must be redrawn when the background graphic is redrawn; when the animation
changes the indicators' positions; or when the indicator color changes.
The control is made up of six circular indicators that travel around the center
of the control. Initially the indicators are grouped together starting at 90 degrees.
The control uses Windows coordinates with the x-axis values increasing to the
right; y-axis values increasing downward; and angles measured clockwise from
Starting with the most clockwise indicator, it is moved 11.25 degrees clockwise.
If the indicator ends up in the fast movement area of the control, on the next pass,
it will be moved some multiple of 11.25 degrees.
The angular advance (11.25) was derived from the desire to have eight indicators
displayed in a quadrant. This results in 32 indicators around the control. Dividing
360 by 32 yields the advance of 11.25 degrees.
Because the trigonometric functions Sine and Cosine are invoked at each indicator
advance, two tables are generated at initialization that contain 1440 values of
the trigonometric functions in increments of 0.25 degrees.
Each of the six indicators is an instance of the Indicator class.
public class Indicator
double degrees = 0.0;
double fast = 1.0;
public Indicator ( )
Degrees = 0.0;
Fast = 1.0;
public Indicator ( double degrees )
Degrees = degrees;
Fast = 1.0;
public double Degrees
return ( degrees );
degrees = value;
public double Fast
return ( fast );
fast = value;
Finally, draw_indicator_graphic is invoked
each time the interval timer raises the elapsed event.
void draw_indicator_graphic ( Graphics graphics )
Brush brush = new SolidBrush ( Indicator_Color );
Rectangle rectangle = new Rectangle ( );
for ( int i = ( MAXIMUM_INDICATORS - 1 );
( i >= 0 );
double degrees = indicators [ i ].Degrees;
if ( degrees < 0.0 )
degrees += 360.0;
dx = round ( ( double ) indicator_center_radius *
cos ( degrees ) ) +
dy = indicator_center_radius -
round ( ( double ) indicator_center_radius *
sin ( degrees ) );
rectangle.Location = new Point ( dx, dy );
rectangle.Size = new Size ( indicator_diameter,
graphics.FillEllipse ( brush, rectangle );
degrees -= ( double ) indicators [ i ].Fast *
if ( indicators [ i ].Fast > 1.0 )
indicators [ i ].Fast += 0.25;
if ( degrees < 0.0 )
indicators [ i ].Fast = 1.25;
else if ( degrees < START_AT )
indicators [ i ].Fast = 1.0;
indicators [ i ].Degrees = degrees;
brush.Dispose ( );
The GraphicsBuffer class contains an off-screen bitmap used to draw graphic objects
without flicker. Although .Net provides a
Buffered Graphics capability, it is overkill for the Win8ProgressRing control.
GraphicsBuffer has been included within the control.
This article has presented a control that mimics the Windows 8 Progress Ring.
Win8ProgressRing control was developed in the following environment:
||Microsoft Windows 7 Professional Service Pack 1
||Microsoft Visual Studio 2008 Professional
||Microsoft .Net Framework Version 3.5 SP1
||Microsoft Visual C# 2008
||Added Demonstration Executable download; performed minor editing; regenerated
Table of Contents with the Auto-TOC Generator