Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Analog Meter

0.00/5 (No votes)
4 Apr 2008 1  
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:

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.

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 :

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here