Skip to main content
Email Password   helpLost your password?

Screenshot - Thermometer_demo.jpg

Introduction

This article demonstrates a complex analog-style thermometer control in C#. The control is in pure managed code. Most visual elements can be adjusted through the control's properties.

Layout

Due to the flexibility of the control, it can be used to display all sorts of data and not just degrees as used in this example.

Screenshot - Layouts.jpg

Architecture

The control consists of 2 classes: ManometerBase and Thermometer.

Screenshot - architecture.jpg

The implementation is done in the Thermometer class.

Code

All painting is done in the OnPaint method of the Thermometer class. Every element has its own Paint method and the methods are marked protected virtual.

protected override void OnPaint(PaintEventArgs e)
{
    // Set smoothingmode to AntiAlias

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    // Shadow

    PaintShadow(e.Graphics);
    // Background

    PaintBackground(e.Graphics);
    // Border

    PaintBorder(e.Graphics);
    // Inner shadow

    PaintInnerShadow(e.Graphics);
    // Bars

    PaintBars(e.Graphics);
    // Numbers

    PaintNumbers(e.Graphics);
    // Paint the text(s)

    PaintText(e.Graphics);
    // Paint the Arrows

    PaintArrows(e.Graphics);
    // Reflex

    PaintReflex(e.Graphics);
    // Reset smoothingmode

    e.Graphics.SmoothingMode = SmoothingMode.Default;
}

Painting the numbers

Most methods are straightforward, but aligning the numbers in the ellipse is somewhat tricky.

protected virtual void PaintNumbers(Graphics g)
{
    double tmpAngle = StartAngle;
    for (double d = Min; d<= Max; d+= Interval)
    {
        String text = Math.Round(d, Decimals).ToString();
        PointF p = 
            CalcTextPosition(
            tmpAngle, MeasureText(g, text, Font, (int)numberRect.Width));
        if (ClockWise)
            tmpAngle -= NumberSpacing;
        else
            tmpAngle += NumberSpacing;
            g.DrawString(text, Font, new SolidBrush(ForeColor), p);
    }
}

The solution is to find the center point of the text and then calculate the offset based on the text's position in the ellipse and its dimensions.

private PointF CalcTextPosition(double a, SizeF size)
{
    PointF p = PointInEllipse(numberRect, a);
    p.X -= (float)((size.Width/2)*(1 + Math.Cos(Convert.ToRadians(a))));
    p.Y -= (float)((size.Height/2)*(1 - Math.Sin(Convert.ToRadians(a))));
    return p;
}

The private method CalcTextPosition makes a call to PointInEllipse. This method calculates a point in an ellipse based on the angle and the size of the ellipse, which is simple math.

private static PointF PointInEllipse(RectangleF rect , double angle)
{
    double r1 = rect.Width/2;
    double r2 = rect.Height/2;
    double x = 
        (float)(r1 * Math.Cos(Convert.ToRadians(angle))) + r1 + rect.X;
    double y = 
        -(float)(r2 * Math.Sin(Convert.ToRadians(angle))) + r2 + rect.Y;
    return new PointF((float)x, (float)y);
}

Using the code

To test the control, download the demo project and then build and run it. To change the appearance of the control, use the properties:

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralKudos, and more kudos Pin
jon_sigler
17:42 30 Dec '08  
GeneralVisual Studio 6 Pin
CodeHead
4:13 27 Feb '08  
GeneralRe: Visual Studio 6 Pin
The Dogcow Farmer
3:31 14 Sep '08  
GeneralPrograming style suggestions! Pin
Martin#
0:53 17 Jul '07  
AnswerRe: Programing style suggestions! Pin
Niel M.Thomas
2:06 18 Jul '07  
GeneralRe: Programing style suggestions! Pin
Martin#
2:13 18 Jul '07  
GeneralRe: Programing style suggestions! Pin
Michal Brylka
10:31 19 Jul '07  
GeneralRe: Programing style suggestions! Pin
Jani Mukkavaara
3:32 24 Jun '08  
GeneralRe: Programing style suggestions! Pin
Martin#
8:04 24 Jun '08  
QuestionAm I doing something wrong? Pin
rob.iles
12:36 29 Jun '07  
GeneralRe: Am I doing something wrong? Pin
rob.iles
13:44 30 Jun '07  
QuestionVery cool, but... Pin
The Marshal
20:28 20 Jun '07  
AnswerRe: Very cool, fixed Pin
Niel M.Thomas
21:43 20 Jun '07  
AnswerRe: Very cool, but... Pin
Kevin Gallagher
7:03 21 Jun '07  
GeneralGood control Pin
nitikin
2:20 19 Jun '07  
GeneralGreat Control Pin
merlin981
4:14 12 Jun '07  
Generalnice, but... Pin
FZelle
21:40 11 Jun '07  
GeneralRe: nice, but... Pin
The Marshal
9:06 21 Jun '07  
GeneralRe: nice, but... Pin
FZelle
22:17 21 Jun '07  
GeneralRe: nice, but... Pin
craigg75
4:59 17 Jul '07  
GeneralRe: nice, but... Pin
FZelle
5:30 17 Jul '07  
Generalkudos Pin
pita2000
17:00 11 Jun '07  
Generallovely Pin
bryce
14:14 11 Jun '07  
GeneralCoool... Pin
Paul Selormey
13:29 11 Jun '07  


Last Updated 9 Jul 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009