5,696,576 members and growing! (16,534 online)
Email Password   helpLost your password?
Desktop Development » Miscellaneous » General     Intermediate License: The Code Project Open License (CPOL)

A thermometer control

By Niel M.Thomas

Creating an analog-style thermometer
C#, Windows, .NET 2.0, .NET, Visual Studio, GDI+, Dev

Posted: 11 Jun 2007
Updated: 9 Jul 2007
Views: 28,243
Bookmarked: 107 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
47 votes for this Article.
Popularity: 7.60 Rating: 4.55 out of 5
2 votes, 4.3%
1
0 votes, 0.0%
2
3 votes, 6.4%
3
8 votes, 17.0%
4
34 votes, 72.3%
5

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:

  • Interval - The interval between each number on the control; this is a floating point number.
  • Max - The maximum on the scale.
  • Min - The minimum on the scale.
  • StartAngle - The starting point in degrees.
  • StoreMax - Show the maximum stored value (red arrow).
  • StoredMax - The stored maximum.
  • TextDescription - Set the lower text displayed on the control.
  • TextUnit - Set the text to describe the Units used.
  • Value - The value and point of the arrow.
  • ArrowColor - The color of the arrow.
  • BackColor - The inner color of the control.
  • BarsBetweenNumbers - The number of lines between two displayed numbers. Note that the alignment of the lines is dependent on the properties NumberSpacing and Interval.
  • BorderWidth - The width of the outer border.
  • ClockWise - Lay the numbers out clockwise or counter-clockwise.
  • Decimals - The number of decimals displayed; default is 0.
  • NumberSpacing - The spacing between the numbers in degrees.

History

  • June 09, 2007: Initial release.
  • July 08, 2007:
    • Fixed missing dispose on some objects.
    • Fixed a bug where the designer would hang if the control was added from the toolbar.
    • Changed default text on Unit and Description property.
    • Added the layout section in this document.
    • Added a demo download.
    • Removed solution from source control.

License

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

About the Author

Niel M.Thomas


Name: Niel Morgan Thomas
Born: 1970 in Denmark
Education:
Dataengineer from Odense Technical University.
More than 10 Year in IT-business.
Current employment:
Working with application development in a major Danish company that produce medical equipment.
Occupation: Software Developer (Senior)
Location: Denmark Denmark

Other popular Miscellaneous articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 23 of 23 (Total in Forum: 23) (Refresh)FirstPrevNext
GeneralVisual Studio 6memberCodeHead4:13 27 Feb '08  
GeneralRe: Visual Studio 6memberThe Dogcow Farmer3:31 14 Sep '08  
GeneralPrograming style suggestions!memberMartin#0:53 17 Jul '07  
AnswerRe: Programing style suggestions!memberNiel M.Thomas2:06 18 Jul '07  
GeneralRe: Programing style suggestions!memberMartin#2:13 18 Jul '07  
GeneralRe: Programing style suggestions!memberMichal Brylka10:31 19 Jul '07  
GeneralRe: Programing style suggestions!memberJani Mukkavaara3:32 24 Jun '08  
GeneralRe: Programing style suggestions!mvpMartin#8:04 24 Jun '08  
QuestionAm I doing something wrong?memberrob.iles12:36 29 Jun '07  
GeneralRe: Am I doing something wrong?memberrob.iles13:44 30 Jun '07  
QuestionVery cool, but...memberThe Marshal20:28 20 Jun '07  
AnswerRe: Very cool, fixedmemberNiel M.Thomas21:43 20 Jun '07  
AnswerRe: Very cool, but...memberKevin Gallagher7:03 21 Jun '07  
GeneralGood controlmembernitikin2:20 19 Jun '07  
GeneralGreat Controlmembermerlin9814:14 12 Jun '07  
Generalnice, but...memberFZelle21:40 11 Jun '07  
GeneralRe: nice, but...memberThe Marshal9:06 21 Jun '07  
GeneralRe: nice, but...memberFZelle22:17 21 Jun '07  
GeneralRe: nice, but...membercraigg754:59 17 Jul '07  
GeneralRe: nice, but...memberFZelle5:30 17 Jul '07  
Generalkudosmemberpita200017:00 11 Jun '07  
Generallovelymemberbryce14:14 11 Jun '07  
GeneralCoool...supporterPaul Selormey13:29 11 Jun '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 9 Jul 2007
Editor: Genevieve Sovereign
Copyright 2007 by Niel M.Thomas
Everything else Copyright © CodeProject, 1999-2008
Web19 | Advertise on the Code Project