Click here to Skip to main content
12,289,383 members (74,678 online)
Click here to Skip to main content
Add your own
alternative version


362 bookmarked

Aqua Gauge

, 4 Sep 2007 CPOL
Rate this:
Please Sign up or sign in to vote.
A Gauge Control Developed using GDI+ with Aqua Skin
Screenshot - AquaGauge.gif


I have chosen to develop this .NET user control to explore the easy yet powerful .NET GDI+. This simple gauge control developed using .NET 2.0 can cater to the entire range of monitoring purposes. Let's see how to develop such a glossy control using GDI+.

Overridden UserControl Methods

Normally, If we create user controls that have been fully drawn by the user, we should override the OnPaint and OnPaintBackground methods. Additionally, the control styles are to be set as appropriate. The following common styles can be set using this.SetStyle(ControlStyles.XXXXX, true/false);.

SupportsTransparentBackColor This will enable your control to support a transparent backcolor if set to true.
ControlStyles.ResizeRedraw Allows repainting when the control is resized.
ControlStyles.AllPaintingInWmPaint If true, the control ignores the window message WM_ERASEBKGND to reduce flicker.
This style should only be applied if the UserPaint bit is set to true.
ControlStyles.UserPaint If true, the control paints itself rather than the operating system doing so.
ControlStyles.OptimizedDoubleBuffer If true, the control is first drawn to a buffer rather than directly to the screen, which can reduce flicker. If you set this property to true, you should also set the AllPaintingInWmPaint to true.

The OnPaint and OnPaintBackground methods will be called whenever the control needs to be repainted. For example, when the control is resized or the form is minimized and maximized, the OnPaint method will be called.

OnPaintBackground vs. OnPaint

OnPaintBackground paints the background (and thereby the shape) of the Window and is guaranteed to be fast. In contrast, OnPaint paints the details and might be slower because individual paint requests are combined into one Paint event that covers all areas that have to be redrawn. You might want to invoke the OnPaintBackground if, for instance, you want to draw a gradient-colored background for your control.

While OnPaintBackground has an event-like nomenclature and takes the same argument as the OnPaint method, OnPaintBackground is not a true event method. There is no PaintBackground event and OnPaintBackground does not invoke event delegates. When overriding the OnPaintBackground method, a derived class is not required to invoke the OnPaintBackground method of its base class.

Drawing the Guage Dial

First, let's see how to draw the dial. The dial requires a Scale, Threshold Indicator, some text and the current value to be displayed.

Drawing the scale requires calculating the positions for the rules that are to be drawn at the circumference. Let's say we need to draw a scale starting from 0 to 10 from angle 90 degrees to 270 degrees on the dial. In this case, the difference in the degrees (270-90 = 180) must be divided into 10 parts. To find the position for each part to be drawn, we need the following formula:

x = centerX + radius * cos(180/partNo)
y = centerY + radius * sin(180/partNo)

Note: when using Math.Cos or Math.Sin we should give angles in radians.

Circle Formula

After finding the position, we can draw any type of scale mark on the circumference. I have chosen to draw a line as a scale mark. Since the dial area is not going to be changed often, it can be drawn in OnPaintBackground overridden method.

Drawing the Pointer

The pointer may need to be repainted often. So, it is better to draw it in the OnPaint method. Finding the pointer position is the same as the logic for drawing the scale. The pointer can be drawn using graphicsObj.FillPolygon() method and it can be transformed to any angle that will represent the current value. Otherwise, the pointer can be redrawn for every change made for the current value.

Drawing the Glossiness

Drawing the glossiness is very simple. All you have to do is, after painting all the dial and pointer, fill two ellipses with gradient coloring. The LinearGradientBrush class provides the ability to draw gradient fills. Masking the gradient layer over the dial gives the glossiness as shown in the below figure.


Using the AquaGauge Control

This AquaGauge control can be used as any other user control provided by Windows. The following are the control-specific properties that can be used to configure this gauge to suit your requirements.

Property Name Type Description
DialColor Color Gets or Sets the background color for the gauge.
DialText String Gets or Sets the Text displayed on the gauge dial.
EnableTransparentBackground bool Enables or Disables Transparent Background color. Note: Enabling this will reduce the performance and may make the control flicker.
Glossiness float Gets or Sets the strength of the Glossiness.
MaxValue float Gets or Sets the maximum value shown on the gauge scale.
MinValue float Gets or Sets the minimum value shown on the gauge scale.
NoOfDivisions int Gets or Sets the number of divisions on the gauge scale.
NoOfSubDivisions int Gets or Sets the number of subdivisions displayed on the scale for each division.
RecommendedValue float Gets or Sets the recommended value on the scale. This will be used as a pivot point for drawing the threshold area.
ThresholdPercent float Gets or Sets the Threshold area percentage on the scale.
Value float Gets or Sets the value to which the pointer will point.

Points of Interest

Whenever we draw images with lots of manipulations, it is recommended to draw it on an image object and then paint. For example, drawing the gauge dial requires lots of CPU-consuming operations. So, we can draw the dial onto an image and then draw using graphicsObj.DrawImage(). Whenever changes are made on the dial properties, we can recreate the image object. It would improve the performance.


  • Version 1.0 - Initial Version

All comments and suggestions are welcome.


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


About the Author

Ambalavanar Thirugnanam
Architect BNY Mellon
India India
Ambalavanar, working as a .NET Solutions Architect at BNY Mellon (iNautix), Chennai. Enjoys designing and developing UI & highly scalable apps.

You may also be interested in...

Comments and Discussions

SuggestionNice component, globalization of digital decimal point Pin
Member 25129777-Jan-14 10:05
memberMember 25129777-Jan-14 10:05 
GeneralMy vote of 5 Pin
cesarms895-Apr-13 6:35
membercesarms895-Apr-13 6:35 
Questionprogramatically create a gauge? Pin
leos7915-Feb-13 20:22
memberleos7915-Feb-13 20:22 
QuestionGauge Needle Update, But Value Does Not Pin
Member 920084522-Aug-12 17:00
memberMember 920084522-Aug-12 17:00 
AnswerRe: Gauge Needle Update, But Value Does Not Pin
Joerg_Laukemper29-Aug-12 0:34
memberJoerg_Laukemper29-Aug-12 0:34 
QuestionRe: Gauge Needle Update, But Value Does Not Pin
Member 1034311325-Feb-14 14:14
memberMember 1034311325-Feb-14 14:14 
GeneralMy vote of 5 Pin
manoj kumar choubey21-Aug-12 18:56
membermanoj kumar choubey21-Aug-12 18:56 
QuestionSmoothness Pin
azizib11-Jun-12 2:46
memberazizib11-Jun-12 2:46 
AnswerRe: Smoothness Pin
Ambalavanar Thirugnanam11-Jun-12 16:58
memberAmbalavanar Thirugnanam11-Jun-12 16:58 
GeneralRe: Smoothness Pin
azizib20-Jun-12 1:18
memberazizib20-Jun-12 1:18 
GeneralRe: Smoothness Pin
arenaxp11-Sep-12 22:24
memberarenaxp11-Sep-12 22:24 
GeneralRe: Smoothness Pin
azizib12-Sep-12 1:13
memberazizib12-Sep-12 1:13 
GeneralRe: Smoothness Pin
arenaxp12-Sep-12 18:27
memberarenaxp12-Sep-12 18:27 
GeneralVery Good! Pin
FrancescoC5-Mar-12 22:54
memberFrancescoC5-Mar-12 22:54 
QuestionHow to refresh the value? Pin
alfred_lok11-Feb-12 6:25
memberalfred_lok11-Feb-12 6:25 
AnswerRe: How to refresh the value? Pin
Dieter Vander Donckt22-Oct-15 22:25
memberDieter Vander Donckt22-Oct-15 22:25 
Generalnice! Pin
jjbubka7-Feb-12 22:42
memberjjbubka7-Feb-12 22:42 
GeneralMy vote of 5 Pin
Redemon7-Dec-11 1:45
memberRedemon7-Dec-11 1:45 
GeneralAwesome! Pin
Member 803356210-Aug-11 9:17
memberMember 803356210-Aug-11 9:17 
GeneralMy vote of 5 Pin
version_2.018-Jun-11 0:17
memberversion_2.018-Jun-11 0:17 
GeneralWonderful control Pin
BeauGauge00120-Mar-11 16:28
memberBeauGauge00120-Mar-11 16:28 
GeneralMy vote of 5 Pin
Frédéric Pailloux25-Jan-11 23:41
memberFrédéric Pailloux25-Jan-11 23:41 
GeneralMy vote of 5 and modifications by me Pin
settorezero2-Jan-11 22:44
membersettorezero2-Jan-11 22:44 
GeneralMy vote of 5 Pin
settorezero2-Jan-11 11:46
membersettorezero2-Jan-11 11:46 
GeneralA little patch Pin
mythzxp31-Dec-09 14:49
membermythzxp31-Dec-09 14:49 
QuestionNeed your help Pin
Jeffreychou7-Jun-09 23:10
memberJeffreychou7-Jun-09 23:10 
GeneralDigit Value quick fix Pin
kelvin199710-May-09 2:05
memberkelvin199710-May-09 2:05 
GeneralRe: Digit Value quick fix Pin
Curros17-May-12 7:12
memberCurros17-May-12 7:12 
GeneralNot truly transparent Pin
mmcguirk14-May-09 10:44
membermmcguirk14-May-09 10:44 
GeneralThank! Pin
buidinhba28-Apr-09 16:48
memberbuidinhba28-Apr-09 16:48 
GeneralUse in ASP.NET Pin
girishdpatil25-Feb-09 0:16
membergirishdpatil25-Feb-09 0:16 
QuestionDouble buffering problem? Pin
c3p00029-Dec-08 10:35
memberc3p00029-Dec-08 10:35 
AnswerRe: Double buffering problem? Pin
Ambalavanar Thirugnanam29-Dec-08 18:15
memberAmbalavanar Thirugnanam29-Dec-08 18:15 
GeneralVery Good Control Pin
Member 313324111-Dec-08 10:25
memberMember 313324111-Dec-08 10:25 
QuestionGreat job....minor problem with drawing digital value?? Pin
some1s6910-Dec-08 10:04
membersome1s6910-Dec-08 10:04 
GeneralVery Nice Pin
JJMatthews4-Dec-08 15:46
memberJJMatthews4-Dec-08 15:46 
GeneralThanks! Pin
Colores214-Nov-08 18:33
memberColores214-Nov-08 18:33 
GeneralDial Text Pin
ashesman12-Oct-08 20:41
memberashesman12-Oct-08 20:41 
GeneralRe: Dial Text Pin
Ambalavanar Thirugnanam17-Oct-08 2:44
memberAmbalavanar Thirugnanam17-Oct-08 2:44 
QuestionHow can I use this control in other language? Pin
jeffri1516-Sep-08 14:29
memberjeffri1516-Sep-08 14:29 
GeneralC++ Version Pin
JimmyO7-Aug-08 23:14
memberJimmyO7-Aug-08 23:14 
GeneralGood and Useful Pin
Angelo Cresta19-Jun-08 2:53
memberAngelo Cresta19-Jun-08 2:53 
GeneralRe: Good and Useful Pin
Ambalavanar Thirugnanam19-Jun-08 17:19
memberAmbalavanar Thirugnanam19-Jun-08 17:19 
GeneralAwesome [modified] Pin
ErnestMoore2-May-08 4:57
memberErnestMoore2-May-08 4:57 
GeneralRe: Awesome Pin
Angelo Cresta18-Jun-08 5:32
memberAngelo Cresta18-Jun-08 5:32 
GeneralVery Nice Very Professional looking Pin
lokiblack18-Apr-08 12:32
memberlokiblack18-Apr-08 12:32 
GeneralRe: Very Nice Very Professional looking Pin
Ambalavanar Thirugnanam18-Apr-08 20:14
memberAmbalavanar Thirugnanam18-Apr-08 20:14 
QuestionCan we used this control in ASP.Net 2.0? Pin
Nikhil_pune13-Mar-08 21:41
memberNikhil_pune13-Mar-08 21:41 
GeneralLove this control Pin
pduffin29-Nov-07 8:45
memberpduffin29-Nov-07 8:45 
GeneralRe: Love this control Pin
Ambalavanar Thirugnanam17-Dec-07 2:58
memberAmbalavanar Thirugnanam17-Dec-07 2: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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160518.1 | Last Updated 4 Sep 2007
Article Copyright 2007 by Ambalavanar Thirugnanam
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid