13,199,311 members (68,748 online)
alternative version

#### Stats

85.9K views
37 bookmarked
Posted 13 Mar 2005

# Old Fashioned Analog Meter Control

, 12 May 2005
 Rate this:
This is an article on creating a control derived from the System.Windows.Form.Control class.

## Introduction

This control class was written to simulate an analog meter or dial and also to learn about creating a custom control. This is an example of a meter. A meter shows the current value of a system. As the value of the system changes the changes get reflected on the meter.

## Background

There aren't too many examples of controls that are derived from the Control class. This is understandable because there is no designer support. MSDN has some samples but they are very simple and can be found here. This article contains only the first part of the project which is making the control itself. I have added some designer support so that the colors of the meter face, border, needle, and numbers can be changed using the properties editor in Visual Studio. Creating Custom Controls-Providing Design Time Support 1 by Kodanda Pani was extremely helpful.

## Using the code

In order to use the meter control, you must add the MeterControl.dll to the Windows Application Project References and to your toolbox under the Windows Forms Tab. Locate the MeterControl in your toolbox and drag it on to your form. The meter is drawn in the center of the form so you will have to adjust the size to fit the meter. In the case of the demo, I am using a tracker bar to change the value of the meter, like this:

private void trackBar1_Scroll(object sender, System.EventArgs e) {
meter1.Angle = trackBar1.Value;
}

Angle is the one property the MeterControl uses to redraw the line in the proper location.

## Points of Interest

In order to draw the numbers on the face and draw the line on the meter, I had to translate the center of the control and then use a transform. This was tricky at best. Here is the code to draw the line that points to the value of the meter.

private void DrawLine(Graphics g, int angle, int offset)
{
Matrix m = new Matrix();
PointF center =
new PointF(this.ClientRectangle.Width/2 ,this.ClientRectangle.Bottom -15 );
m.RotateAt( angle+180, center );
m.Translate( center.X, center.Y );
g.Transform = m;
g.DrawLine( meterlinePen, 0, 0, this.ClientRectangle.Width/2 + offset , 0 );

}

## Notes

Next I'll be looking to add some flexibility for drawing the numbers on the face of the meter. Any suggestions would be most welcomed.

## History

• May 13 2005
1. Made changes suggested by Mav.Northwind to fix flicker. Initialized angle to zero in constructor to draw line at resting place. Added Invalidate to the Angle property instead of using an event to redraw the meter.
2. Added regions to make the meter control code easier to read, less cluttered.
3. Added designer support to customize the look and feel of the control.

A list of licenses authors might use can be found here

## Share

 United States
No Biography provided

## You may also be interested in...

 Pro

 First Prev Next
 Allow Min and Max values rather than 0 to 180 stensones30-May-07 23:52 stensones 30-May-07 23:52
 how to make it full circled meter Sridhar Manoharan15-Nov-06 1:18 Sridhar Manoharan 15-Nov-06 1:18
 Fixing flicker mav.northwind13-Mar-05 20:44 mav.northwind 13-Mar-05 20:44
 Hi! Nice control, although the way you implemented the drawing seems to be a bit awkward... You can get rid of Meter_angleChanged() completely and change the set part of your Angle property to this:set { this.angle = value; Invalidate(); } In your OnPaint override you shouldn't set this.angle to 0, or else you'll overwrite the value the user has set. If you change it this way, you'll get a flicker free control that'll keep the angle:Graphics g = Pe.Graphics; DrawPie(g); FillPie(g); this.offset= -30; //-30 is the offset for when the line is pointing to // zero or 180. It would be ideal to change the offset // gradually to -10 as it reaches 270. I'll leave this // for the next version DrawLine(g, angle, offset); for ( int a = 0; a < 360; a += 20) { DrawScale(g, a, 180); } And you should check your Dispose() calls, outlinePen gets disposed too often. Regards, mav
 Re: Fixing flicker seagrrl15-Mar-05 20:04 seagrrl 15-Mar-05 20:04
 Re: Fixing flicker mmcguirk122-Mar-05 4:54 mmcguirk1 22-Mar-05 4:54
 Last Visit: 31-Dec-99 18:00     Last Update: 22-Oct-17 7:46 Refresh 1