shows you how to build a fast and performing control
using C# and .NET
I wrote a similar control
as an ActiveX once, using C++,
ATL, and GDI,
and wondered if it is possible to write performing code
using .NET and GDI+.
I needed it for another project. So I wrote this little control
to show that it actually works.
How the code
The code consists of a C#
application and a custom control. The custom control
really is the interesting part.
Deriving from Control
We derive from
as this doesn't give us all these properties we don't
actually need like a usercontrol would give us, for
public partial class AGauge : Control
Well, there are still
properties that show up in the designer that are not
necessary. In C#,
you can use the
keyword to get rid of them (shadows in VB).
public new Boolean AllowDrop, AutoSize, ForeColor, ImeMode
For properties that you
want to use but with a different behaviour, you can use
keyword (if overrideable) to tell the program to call
this overridden property instead of the implementation
of the base class, which in our case is the
public override System.Drawing.Color BackColor..
public override System.Drawing.Font Font..
public override System.Windows.Forms.ImageLayout BackgroundImageLayout..
To be able to further
customize the control in the designer, we need to add
some properties of our own. E.g.,
public Single Value..
attribute tells the designer to show the property in the
toolbox or not. The
tells the designer where to show the property if the
categorized view is selected, and the
attribute adds a description to the property that the
designer can show in the toolbox.
Events and Delegates
An event can carry
additional information that is sent to the
"listening" program, e.g., the form's event
handler for this event.
Custom event arguments
We want the event to
carry the number of the range the needle is in (if it
changes from being in one range to being in another). To
add some data to the event, we derive from the standard
event args and add a variable which is initialized in
the constructor. This will hold the extra information
public class ValueInRangeChangedEventArgs : EventArgs
public Int32 valueInRange;
public ValueInRangeChangedEventArgs(Int32 valueInRange)
this.valueInRange = valueInRange;
The event handler
"listening" for our event needs to be of a
type that "understands" our event. With the
delegate statement, we define this type.
public delegate void ValueInRangeChangedDelegate(Object sender,
And the event
[Description("This event is raised if the value falls into a defined range.")]
public event ValueInRangeChangedDelegate ValueInRangeChanged;
The event is of the
type we defined in the delegate statement. The
attribute enables the designer to show a description for
the event in the Toolbox.
The constructor is
called when the control
is created, e.g., before it will be shown in the
designer. Here, we set the style of the control to
enable double buffering. This isn't really necessary
since we will do our own double buffering, but it
doesn't hurt to do so.
We need to override
some of the member functions.
First, we override
to ensure that the background is not painted each time
the control is
refreshed, this uses too much CPU even if double
buffering is enabled. One drawback is that we need to
handle the drawing of a background image ourselves, but
this isn't too much of a problem.
protected override void OnPaintBackground(PaintEventArgs pevent)
If the control
is resized, we need to refresh it. So we override
protected override void OnResize(EventArgs e)
drawGaugeBackground = true;
The global variable
drawGaugeBackground" is set to
to tell the control
to completely redraw itself.
the control to redraw, or if you like to call
under the hood, a Windows message is sent, but this is a
Finally, we need to
OnPaint to show some output to the
This is what our
control really does, it shows the output to the user. It
doesn't handle user input like a scrollbar would do. A
scrollbar would override
OnKeyPressed, and so on.
is the heart of our control.
protected override void OnPaint(PaintEventArgs pe)
which is called every time the control
is redrawn, e.g., if the value of the gauge
changed, determines if it should completely redraw
itself or simply paint the background part with the
DrawImage. If the
background hasn't changed, it only needs to draw
the needle, thus avoiding costly GDI+
functions to be called every time. The background
changes, e.g., if a property like a color has changed,
or the control is
resized, for example.
So it really is
possible to write fast and performing controls with GDI+
if we use double buffering and blitting (
If you like VB better
than C#, you can
search for "SpeedyHMI" on SourceForge, this
project I wrote contains this gauge
written in VB.
build, run and, Enjoy!
Capture Print Screen to
Full Screen with
Diagram Like Microsoft Visio 2007
MFC Example: Rows of CToolBar and
CBRS_ALIGN_TOP , CBRS_SIZE_DYNAMIC and
VC++ MFC Source Code
Free Draw .NET GDI+ Gauge Control
with Source Code
Multiple Views layout of
RepositionBars and DeferWindowPos with
RecalcLayout and UpdateAllViews
2008 Feature Pack:
Studio Office 2007 Style Enhancements
VC++ MFC Project Setting, Unicode,
Draw or display Real-time data
VC++ Ado Tutorial
with VC++ Ado Sample and VC++ Ado Example
Screen Capture , to Clipboard, C++ Source Code,
Get bitmap of Window
Draw, Print and encode UPCA barcode
and UPCE barcode, and EAN13 barcode
with VC++ Codes
Create Database with SQL Server and ADO Stored
C++ Barcode source codes
with draw Code39 Code93 AND Code128A
Code128B with Code128C
Converter Convert RTF to HTML
with VC++ Source Codes, and
Real time software
Chart VC++ Source Code
MFC Sample Code: Load and Display
PNG Image File
Introduction to GDI+ in
High-speed Charting Control, Real Time Chart,
Data Visualization, C# Source Code
WPF 3D Article, Tutorial with Chart Graphics C#
Date-Time Edit Control
A simple mucancode.neted
date-time editor. VC++
Article Source Code
Visual C++ Article:
free image library
image viewer with
CxImage and CListCtrl
Graphics Editor With Source Code
HMI & SCADA Solution.
Add proto - logic diagram displays to your
Java, C++, and .NET applications, for the desktop and rich
Diagram Component / Drawing C++ Source Code Solution
it will save you 50% - 80% time for building any UML
MFC or native C/VC++