Click here to Skip to main content
15,881,882 members
Articles / Multimedia / GDI+
Article

Analog Meter

Rate me:
Please Sign up or sign in to vote.
4.12/5 (19 votes)
4 Apr 2008CPOL2 min read 65.6K   4.2K   74   4
Analog meter control with the possibility to set a custom renderer

Introduction

On the internet I found many projects on analog meters, but few could change their appearance using a custom renderer. Because of this, I decided to create my first control in C#, and use this control in my next projects.

Background

To compile this demo you need .NET 2.0 which is available here. The project is developed with SharpDevelop, a free IDE per .NET.

Using the Code

In the zip files there is a complete solution, but it is simple enough to use the code of the control for inserting this in another project. In the next section, there is a description for how to use the class.

Control Class

The class is derived from System.Windows.Forms.UserControl. Normally, this class has a default renderer class that is used for drawing all parties, but it is possible to set a custom renderer to draw a single part, or the entire control. The main class of the control is:

C#
namespace LBSoft.IndustrialCtrls.Meters
{
    ///
    /// Class for the analog meter control
    ///
    
    public partial class LBAnalogMeter : UserControl
    {        

    ...

    }
}

You can set the following properties at design time:

Appearance Properties

  • MeterStyle - Style of the control. At the moment the only stile is AnalogMeterStyle.Circular.
  • BodyColor - Color of the body of the control.
  • NeedleColor - Color of the needle of the control
  • ScaleColor - Color of the thicks of the control scale
  • ScaleDivisions - Number of main division of the scale
  • ScaleSubDivisions - Number of the sub-division between a main division to an other of the scale
  • ViewGlass - Flag for the visualization of the glass effect

Behavior Properties

  • Value - Current value of the control
  • MinValue - Minimum value of the control
  • MaxValue - Maximum value of the control

In the next section will describe the renderer class and how it is possible to customize the control draw.

Renderer Class

The renderer class is a class with a few virtual methods which are called for the design of the individual parts of control.

C#
namespace LBSoft.IndustrialCtrls.Meters
{
    ///
    /// Base class for the renderers of the analog meter
    ///
    public class LBAnalogMeterRenderer
    {
        ///
        /// Control to render
        ///
        private LBAnalogMeter meter = null;
        
        ///
        /// Control properties
        //
        public LBAnalogMeter AnalogMeter
        {
            set { this.meter = value; } 
            get { return this.meter; } 
        }
        
        ///
        /// Draw the background of the control
        ///
        public virtual bool DrawBackground( Graphics gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the body of the control
        ///
        public virtual bool DrawBody( Graphics Gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the scale of the control
        ///
        public virtual bool DrawDivisions( Graphics Gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the thresholds 
        ///
        public virtual bool DrawThresholds( Graphics gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Drawt the unit measure of the control
        ///
        public virtual bool DrawUM( Graphics gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the current value in numerical form
        ///
        public virtual bool DrawValue( Graphics gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the needle 
        ///
        public virtual bool DrawNeedle( Graphics Gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the needle cover at the center
        ///
        public virtual bool DrawNeedleCover( Graphics Gr, RectangleF rc )
        {
            return false;
        }
        
        ///
        /// Draw the glass effect
        ///
        public virtual bool DrawGlass( Graphics Gr, RectangleF rc )        
        {
            return false;
        }
    }
}

All the methods of the base class return False. The control class, if it has a custom renderer, call the custom renderer, and if the method called returns False, call the same method of the default renderer.

For example, if you want to eliminate the drawing of the body of the control, use the following this steps :

  • Create a class derived from LBAnalogMeterRenderer
  • Override the method DrawBody
  • In this method return True
  • Create an instance of the custom renderer in the main form
  • Set the renderer to the control with the property Renderer

Code :

C#
namespace TestApp
{
    ///
    /// Custom renderer
    ///
    public class LBNoBodyAnalogMeterRenderer : LBAnalogMeterRenderer
    {
        public override bool DrawBody( Graphics Gr, RectangleF rc )
        {
            return true;
        }
    }
    
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        // Declare the renderer members of the form
        LBNoBodyAnalogMeterRenderer customRenderer = null;
        ...
        
        public MainForm()
        {
            InitializeComponent();
            
            // Create the renderer
            this.customRenderer = new LBNoBodyAnalogMeterRenderer;
            
            // Set the renderer
            this.lbAnalogMeter.Renderer = this.customRenderer;
            ...
        }
        ...
    }
}

Conclusion

This is the preliminary version of the control, and many features have yet to be implemented, but I hope to do so soon

For this article, I used the code and ideas from this article:

Points of Interest

Any suggestions/comments/feedback are highly appreciated

History

  • 0.1 (04 Apr 2008)
    • Preliminary version

License

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


Written By
Software Developer (Senior) Promax Srl
Italy Italy
Software developer with over 16 years of experience, specializing on MFC/C++, C# and software architecture


Company : Promax S.r.l.


Comments and Discussions

 
Generalthank you Pin
leesong14-Aug-14 1:59
leesong14-Aug-14 1:59 
GeneralCan I use this code for my company project Pin
baleeindia28-Apr-11 4:09
baleeindia28-Apr-11 4:09 
GeneralRe: Can I use this code for my company project Pin
Luca Bonotto30-Apr-11 4:29
Luca Bonotto30-Apr-11 4:29 
GeneralRe: Can I use this code for my company project Pin
baleeindia1-May-11 20:01
baleeindia1-May-11 20:01 

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.