Click here to Skip to main content
12,821,670 members (29,707 online)
Click here to Skip to main content
Add your own
alternative version


194 bookmarked
Posted 29 Sep 2010

A Simple Vector-Based LED User Control

, 5 Apr 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
The LEDBulb is a .NET user control for Windows Forms that emulates an LED light. Its purpose is to provide a sleek looking representation of an LED light that is sizable, has a transparent background and can be set to different colors.


The LEDBulb is a .NET user control for Windows Forms that emulates an LED light with two states On and Off. The purpose of the control is to provide a sleek looking representation of an LED light that is sizable, has a transparent background and can be set to different colors.

LedBulb bulb = new LedBulb();
bulb.Size = new Size(25, 25);
bulb.Color = Color.LawnGreen;
bulb.On = true;


I recently needed to add a custom user control to a Window Forms project of mine that would represent an LED bulb commonly seen on household electronics. After a quick search, most of the existing controls I found were ugly and used static images, which means they wouldn’t scale well. This control uses the System.Drawing.Drawing2D namespace to draw a vector image so that it not only looks clean but will also scale to any size without affecting the image quality.


Rendering the control starts with drawing a solid circle with our background color. Then we draw a radial gradient over it with our highlight color, transitioning to transparent. To draw the reflection, we draw another radial gradient, from white to transparent, but in a smaller rectangle shifted up and left. To prevent the white gradient from showing up outside the bulb, we set the clip parameter to the bounds of our original circle.

// Fill in the background circle 
g.FillEllipse(new SolidBrush(darkColor), drawRectangle);

// Draw the glow gradient
GraphicsPath path = new GraphicsPath();
PathGradientBrush pathBrush = new PathGradientBrush(path);
pathBrush.CenterColor = lightColor;
pathBrush.SurroundColors = new Color[] { Color.FromArgb(0, lightColor) };
g.FillEllipse(pathBrush, drawRectangle);

// Set the clip boundary to the edge of the ellipse
GraphicsPath gp = new GraphicsPath();

// Draw the white reflection gradient
GraphicsPath path1 = new GraphicsPath();
path1.AddEllipse(whiteRectangle); // a smaller rectangle set to the top left
PathGradientBrush pathBrush1 = new PathGradientBrush(path);
pathBrush1.CenterColor = Color.FromArgb(180, 255, 255, 255);
pathBrush1.SurroundColors = new Color[] { Color.FromArgb(0, 255, 255, 255) };
g.FillEllipse(pathBrush1, whiteRect);

Transparent Background

It is important that this control has a transparent background. To do this, we need to add a command to the constructor.

    | ControlStyles.AllPaintingInWmPaint
    | ControlStyles.ResizeRedraw
    | ControlStyles.UserPaint
    | ControlStyles.SupportsTransparentBackColor, true

Customizable Colors

You can customize the color of the LED display by setting the Color property. Setting this property also automatically calculates two other Properties ColorDark and ColorDarkDark which are used for gradients when the control is drawn. These colors are calculated using the using the ControlPaint class, a Control helper class in the System.Windows.Forms namespace.

this.DarkColor = ControlPaint.Dark(_this.Color);
this.DarkDarkColor = ControlPaint.DarkDark(_this.Color); 



The control has a blink method that will make the control start blinking. You pass the number of milliseconds between blinks. To turn the blinking off just call the blink function again passing 0 as the argument.

led.Blink(2000); // Slow blink
led.Blink(500);  // Fast blink
led.Blink(0);    // Turn off blinking

Points of Interest

This control uses double-buffering by drawing its image to an off-screen bitmap first, then sending the final rendering to the client. Double buffering creates a smoother drawing of the control and avoids flicker when moving or re-sizing. The code to accomplish this is below.

protected override void OnPaint(PaintEventArgs e){
    // Create an offscreen graphics object for double buffering
    Bitmap offScreenBmp = new Bitmap(this.ClientRectangle.Width, 
    System.Drawing.Graphics g = Graphics.FromImage(offScreenBmp);
    g.SmoothingMode = SmoothingMode.HighQuality;

    // Render the control to the off-screen bitmap

    // Draw the image to the screen
    e.Graphics.DrawImageUnscaled(offScreenBmp, 0, 0);    



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


About the Author

Steve Marsh
Software Developer (Senior)
United States United States
Stephen Marsh has over 10 years of experience developing enterprise applications built on the .Net framework. He specializes in building expert systems that serve the financial industry.

You may also be interested in...


Comments and Discussions

QuestionIt's just what I'm looking for. Pin
Member 1306344521-Mar-17 15:46
memberMember 1306344521-Mar-17 15:46 
AnswerRe: It's just what I'm looking for. Pin
pitoloko25-Mar-17 6:50
memberpitoloko25-Mar-17 6:50 
QuestionHow can I use this? Pin
Member 128375247-Nov-16 10:04
memberMember 128375247-Nov-16 10:04 
QuestionUsing this in a WPF Project Pin
Member 127212505-Sep-16 8:40
memberMember 127212505-Sep-16 8:40 
AnswerRe: Using this in a WPF Project Pin
Da_Hero26-Oct-16 3:24
memberDa_Hero26-Oct-16 3:24 
GeneralMy vote of 5 Pin
backupluis31-Jan-16 18:13
memberbackupluis31-Jan-16 18:13 
QuestionGreat control! What a pity! The source is unavailable. Pin
wwx395331-Jul-15 15:07
memberwwx395331-Jul-15 15:07 
QuestionResources are not disposed Pin
getthecodeforme23-Jan-15 14:50
membergetthecodeforme23-Jan-15 14:50 
AnswerRe: Resources are not disposed Pin
TymekDP6-Feb-15 0:34
memberTymekDP6-Feb-15 0:34 
QuestionWhy doesn't the Bulb.ledBulb show up in the toolbox? Pin
blipton5-Nov-14 19:48
memberblipton5-Nov-14 19:48 
QuestionMy vote of 5 Pin
chen_zd2-Apr-14 18:50
memberchen_zd2-Apr-14 18:50 
GeneralMy vote of 5 Pin
time-master29-Mar-14 8:16
membertime-master29-Mar-14 8:16 
Questionvote of 5 Pin
CoffeeShop27-Aug-13 21:52
memberCoffeeShop27-Aug-13 21:52 
GeneralMy vote of 5 Pin
TechnoGeek0015-Apr-13 19:00
memberTechnoGeek0015-Apr-13 19:00 
Questionflashing Pin
dano2119-Oct-12 10:28
memberdano2119-Oct-12 10:28 
AnswerRe: flashing Pin
Steve Marsh5-Apr-13 10:23
memberSteve Marsh5-Apr-13 10:23 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 9:39
mvpKanasz Robert27-Sep-12 9:39 
QuestionRight side does not show up! Pin
Saeid Yazdani15-Jul-12 6:16
memberSaeid Yazdani15-Jul-12 6:16 
AnswerRe: Right side does not show up! Pin
Puddin Tame23-Mar-13 18:07
memberPuddin Tame23-Mar-13 18:07 
It appears the bottom edge is also clipped, as well as the right edge.

This is a classic graphics issue. The ellipse being drawn should be one pixel smaller than the enclosing rectangle.

I have also discovered another problem. In a button click event, I was trying to turn the LED on, do some time consumign communication tasks and then turn the LED off. For some reason, I haven't yet determined, the LED never turns on.
GeneralRe: Right side does not show up! Pin
Steve Marsh5-Apr-13 10:21
memberSteve Marsh5-Apr-13 10:21 
QuestionThanks Pin
Fastfootskater2-Apr-12 21:25
memberFastfootskater2-Apr-12 21:25 
GeneralMy vote of 5 Pin
Jon Gunnar Brekke27-Mar-12 12:14
memberJon Gunnar Brekke27-Mar-12 12:14 
GeneralMy vote of 5 Pin
Paul Tobey21-Sep-11 12:43
memberPaul Tobey21-Sep-11 12:43 
GeneralMy vote of 5 Pin
Crusty Applesniffer14-Oct-10 10:03
memberCrusty Applesniffer14-Oct-10 10:03 
GeneralFive vote! Pin
fredsparkle11-Oct-10 14:46
memberfredsparkle11-Oct-10 14:46 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170308.1 | Last Updated 5 Apr 2013
Article Copyright 2010 by Steve Marsh
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid