This short article presents a
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
used internally by the software are displayed in
Table of Contents
The symbol [^] returns the reader
to the top of the Table of Contents.
Visual Properties [^]
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 red.
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
is set equal to the
The indicator color defaults to white. To change the indicator
color, the developer specifies the new color through the
The control's background color is transparent and cannot be
Control Properties [^]
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
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
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
User-Drawn Control. Parts of the control are drawn when the
OnPaint method is invoked.
The control's graphic is made up of two distinct
graphic images: the background graphic and the indicator
Once drawn, the background graphic does not need to be redrawn
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 counterclockwise from the x-axis.
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;
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 ( );
Graphics Buffer [^]
The GraphicsBuffer class contains an off-screen bitmap used to draw
graphic objects without flicker. Although .Net provides a
Double Buffered Graphics capability, it is overkill for the
GraphicsBuffer has been included within the control.
This article has presented a control that mimics the Windows 8
Development Environment [^]
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