Click here to Skip to main content
14,357,666 members

CircleControl - A Circular Motion Control

Rate this:
4.85 (72 votes)
Please Sign up or sign in to vote.
4.85 (72 votes)
13 Jun 2015CPOL
A circular motion control


This is release 1.2.3 of the library. It fixes a bug where CircleControl.AngleChanged() was not always being triggered for mouse up or down events. Added a feature to the EditDefaults sample application to display the most recent AngleChangedArgs.

The CircleControl class is a .NET 2.0 control which allows circular motion, for example, rotating a dial, or setting the hands on an analog clock.

The control supports markers - graphical objects which can be positioned programatically and/or dragged with the mouse, and marker sets, which are groups of markers which move in unison. The background may be populated with colored rings, tick marks, and text strings.

Image 1   Image 2

All public and protected classes, methods and properties and fully documented using standard C# XML documentation comments. The project includes a HTML help file. Refer to the Overview section in the help file for more details on using the class, and refer to the Sample Program section for a complete source listing of a working application.

The CircleControl_123_Library download includes:

CircleControl.dll Class library
CircleControl.chm Help file.

The CircleControl_123_Demo download includes the above files, as well as:

AnalogClock.exe Sample program showing an analog clock; the time may be changed by dragging the hour and minute hands.
ColorDialer.exe Sample program for picking a color; rotate the red, blue, and green dials to select the RGB values. The program is visually gratuitous demonstration of the control, and is not meant to be a serious color picker.
EditDefaults.exe Sample program demonstrating the effect of changing various CircleControl properties. It also demonstrates the new Snap feature.
GantryControl.exe Sample program as detailed in the Sample Program section of the help file.
ManyRings.exe Sample program showing excessive use of rings. Includes capability to compare paint times with <c>FixedBackground set to <c>true or <c>false.

The CircleControl_123_Source download includes the source for all of above programs, as well as the necessary files for building the help file.

Compatibility with Other .NET Framework Versions

The CircleControl library is compiled using .NET Framework version 2.0. To confirm that there were no issues with other framework versions, the compiled library was used by an application which was compiled, in turn, under .NET Framework versions 3.0, 3.5, 4.0, and 4.5. The CircleControl functioned properly with all of them.

Using the code

To use the CircleControl class, simply add it on an existing form:

CircleControl cc = new CircleControl();
cc.Location = new System.Drawing.Point(0, 0);
cc.Size = new System.Drawing.Size(200, 200);

By default, a new instance of CircleControl comes ready to use with a single triangular marker and ten tick marks.

To add a new marker, create a new MarkerSet, and add one or more Marker objects:

CircleControl.MarkerSet ms = new CircleControl.MarkerSet();

// Polygon which defines shape of marker
PointF[] poly = new PointF[4];
poly[0] = new PointF(0.25F,  0.00F);
poly[1] = new PointF(0.70F,  0.18F);
poly[2] = new PointF(0.64F,  0.00F);
poly[3] = new PointF(0.70F, -0.18F);

CircleControl.Marker m = new CircleControl.Marker(
                  Color.Brown,       // inside color
                  Color.DarkGreen,   // border color
                  1.0f,              // border thickness
                  poly,              // polygon defining marker shape
                  130.0f,            // angle offset of marker
                  MouseButtons.Left, // which button(s) can drag the marker
                  true);             // is marker visible?

// Add new marker to MarkerSet, at which point
// it becomes visible on the control

The polygon defines the appearance of the marker at angle zero. It uses a cartesian coordinate system, where (0,0) is the center of the control, and 1.0 is the distance to the nearest edge. The internal area of a marker can be a solid color, a hatch pattern, or a variety of color gradients. Borders can be of any color and thickness.

An AngleChanged event is raised whenever the angle of a marker changes, or the mouse state of a dragged marker changes. To receive events, install a handler:

cc.AngleChanged += new CircleControl.AngleChangedHandler(OnAngleChange);

The background may be populated with colored rings, tick marks, and text strings. The following code snippet adds a beige-colored ring, and four text items, as they would be placed on a compass:

cc.Rings.Add(new CircleControl.Ring(0.6f,        // size as radius
                                    Color.Beige, // internal color
                                    Color.Black, // border color
                                    2.0f);       // border thickness

Font f = new Font("Arial", 8.0f);
cc.TextItems.Add(new CircleControl.TextItem(f,         // font
                                            Color.Red, // color
                                            "N",       // text
                                            0.8f,      // distance from origin
                                            90.0f);    // angle
cc.TextItems.Add(new CircleControl.TextItem(f, Color.Red, "S", 0.8f, 270.0f);
cc.TextItems.Add(new CircleControl.TextItem(f, Color.Red, "E", 0.8f,   0.0f);
cc.TextItems.Add(new CircleControl.TextItem(f, Color.Red, "W", 0.8f, 180.0f);

The internal area of a ring can be a solid color, a hatch pattern, or a variety of color gradients. Borders can be of any color and thickness. Text items can be of any font, color, or rotation. They can be a fixed size, or made to be relative to the size of the control.

The above code snippets only provide a brief overview. Refer to project help file for complete class documentation.

Points of Interest

Writing, refining, and debugging the code was, as always, a joyful experience. But documenting every public and protected class, method and property was not. It was drudgery. The pain of writing full and proper documentation was offset in part by Sandcastle Help File Builder, a freely available tool used to generate the help file. But documenting everything was a learning experience, and I've developed immense respect for programmers who write complete and useful documentation, especially for those at Microsoft who are responsible for the creation of the extensive .NET documentation.


  • June 13, 2015 - Release 1.2.3
    • Fixed a bug where CircleControl.AngleChanged() was not always being triggered for mouse up and mouse down events,
  • September 5, 2014 - Release 1.2.2
    • Corrected minor documentation errors,
    • Converted .csproj files to Visual Studio 2013 format.
    • Converted help files to work with SandCastle Help File Builder 2014.5.31.0.
  • September 14, 2013 - Release 1.2.1
    • Fixed bug in private method <c>CircleControl.MarkerSet.CalcSnapDist() where the snap angle may be improperly calculated if <c>CircleControl.AngleWraps is <c>false.
  • September 8, 2012 - Release 1.2
    • Added <c>SnapMode and <c>SnapAngles properties <c>CircleControl.MarkerSet.
  • July 21, 2011 - Release 1.1.2
    • Fixed bug in <c>CircleControl.Collections.Insert() method where the Cc parameter was improperly being set to <c>null.
  • November 1, 2010 - Release 1.1.1
    • Fixed bug in <c>CircleControl.SetAngleMinMax() method where the call was ignored unless both <c>min and <c>max parameters were different from the current values.
    • Fixed bug where marker angles were not always calculated properly if <c>AngleWraps was <c>false.
  • October 12, 2010 - Release 1.1
    • Added <c>FixedBackground property to <c>CircleControl.
  • September 12, 2010 - First release


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Graham Wilson
Software Developer (Senior)
Canada Canada
No Biography provided

Comments and Discussions

QuestionHow to use CireControl.dll in VC++ Dialog based application Pin
sanjeevKS120417-Aug-17 2:53
membersanjeevKS120417-Aug-17 2:53 
AnswerRe: How to use CireControl.dll in VC++ Dialog based application Pin
Graham Wilson17-Aug-17 10:58
memberGraham Wilson17-Aug-17 10:58 
SuggestionCircular control and hotkeys Pin
jcastor16-Jun-15 6:04
memberjcastor16-Jun-15 6:04 
GeneralRe: Circular control and hotkeys Pin
Graham Wilson16-Jun-15 6:27
memberGraham Wilson16-Jun-15 6:27 
QuestionBug fixed in < 12 hrs Pin
IrkedScientist15-Jun-15 10:37
memberIrkedScientist15-Jun-15 10:37 
GeneralGreat Job!! Pin
dbrownn21-Jan-15 6:44
memberdbrownn21-Jan-15 6:44 
GeneralRe: Great Job!! Pin
Graham Wilson21-Jan-15 8:17
memberGraham Wilson21-Jan-15 8:17 
GeneralMy vote of 5 Pin
Volynsky Alex7-Sep-14 11:47
professionalVolynsky Alex7-Sep-14 11:47 
GeneralMy vote of 5 Pin
Anurag Gandhi6-Sep-14 0:09
professionalAnurag Gandhi6-Sep-14 0:09 
GeneralRe: My vote of 5 Pin
Graham Wilson6-Sep-14 2:35
memberGraham Wilson6-Sep-14 2:35 
GeneralMy vote of 5 Pin
Johann Krenn15-Sep-13 0:49
memberJohann Krenn15-Sep-13 0:49 
GeneralRe: My vote of 5 Pin
Graham Wilson15-Sep-13 16:37
memberGraham Wilson15-Sep-13 16:37 
QuestionGreat Work!! Pin
Aureocad27-Aug-13 0:20
memberAureocad27-Aug-13 0:20 
AnswerRe: Great Work!! Pin
Graham Wilson15-Sep-13 16:37
memberGraham Wilson15-Sep-13 16:37 
GeneralMy vote of 5 Pin
KD0YU30-Nov-12 4:13
memberKD0YU30-Nov-12 4:13 
QuestionCool Pin
sam.hill8-Sep-12 17:27
membersam.hill8-Sep-12 17:27 
QuestionInvert Primary Marker Pin
Todd Denlinger8-Aug-12 13:07
memberTodd Denlinger8-Aug-12 13:07 
AnswerRe: Invert Primary Marker Pin
Graham Wilson8-Aug-12 16:58
memberGraham Wilson8-Aug-12 16:58 
GeneralRe: Invert Primary Marker Pin
Todd Denlinger9-Aug-12 5:27
memberTodd Denlinger9-Aug-12 5:27 
GeneralMy vote of 5 Pin
ProEnggSoft13-Mar-12 2:06
memberProEnggSoft13-Mar-12 2:06 
GeneralMy vote of 4 Pin
mariazingzing15-Feb-12 13:56
membermariazingzing15-Feb-12 13:56 
GeneralMy vote of 5 Pin
peteSJ22-Jul-11 7:57
memberpeteSJ22-Jul-11 7:57 
Questionexcellent, and fully documented code Pin
BillWoodruff21-Jul-11 13:06
mveBillWoodruff21-Jul-11 13:06 
QuestionCool Pin
BillW3321-Jul-11 6:22
professionalBillW3321-Jul-11 6:22 
QuestionGood work Pin
Shahriar Iqbal Chowdhury/Galib21-Jul-11 5:58
professionalShahriar Iqbal Chowdhury/Galib21-Jul-11 5:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Posted 12 Sep 2010


194 bookmarked