Click here to Skip to main content
Licence CPOL
First Posted 29 Sep 2010
Views 23,937
Downloads 1,886
Bookmarked 107 times

A Simple Vector-Based LED User Control

By | 5 Oct 2010 | Article
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.
sshot-1.png

Introduction

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;
this.Controls.Add(bulb); 

Sizeable

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.

sshot-3.png

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();
path.AddEllipse(drawRectangle);
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();
gp.AddEllipse(drawRectangle);
g.SetClip(gp);

// 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 override a few methods in our control.

protected override CreateParams CreateParams {
    get {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x20;
        return cp;
    }
}

protected override void OnMove(EventArgs e) {
    RecreateHandle();
}
		
protected override void OnPaintBackground(PaintEventArgs e) {
    // Do nothing
}

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); 
sshot-6.png

sshot-5.png

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 resizing. The code to accomplish this is below. This technique works great on most controls, however the transparent background of this control means that the parent is responsible for drawing the background of our control so we still get a flicker when resizing. Fortunately the LEDBulb probably won’t need to be actively resized, but any suggestions on how to solve this would be appreciated.

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

	// Render the control to the off-screen bitmap
	drawControl(g);

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

Links

License

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

Member

Stephen Marsh has over 8 years of experience developing enterprise web applications using web standards and the .Net framework. He has extensive experience in web technologies including XML, XSLT, JavaScript, Ajax and CSS.
 
Stephen currently works on projects that promote web standards, SOA and SaaS methodologies. Stephen's expertise is in the development of user-centered software for non-technical users.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionThanks PinmemberFastfootskater20:25 2 Apr '12  
GeneralMy vote of 5 [modified] PinmemberJon Gunnar Brekke11:14 27 Mar '12  
GeneralMy vote of 5 PinmemberPaul Tobey11:43 21 Sep '11  
GeneralMy vote of 5 PinmemberCrusty Applesniffer9:03 14 Oct '10  
GeneralFive vote! Pinmemberfredsparkle13:46 11 Oct '10  
GeneralMy vote of 5 Pinmemberfredsparkle13:43 11 Oct '10  
GeneralOne little thing PinmemberKelvin Armstrong1:54 9 Oct '10  
GeneralRe: One little thing PinmemberSteve Marsh7:19 14 Oct '10  
GeneralControl tricks PinmemberNicolasG10:13 6 Oct '10  
GeneralRe: Control tricks PinmemberSteve Marsh7:18 14 Oct '10  
GeneralMy vote of 5 Pinmemberdave.kelly6:49 6 Oct '10  
GeneralVote of 5 PinmemberKelvin Armstrong22:01 5 Oct '10  
GeneralMy vote of 4 PinmemberSunil Soni21:50 4 Oct '10  
Generalthoughts PinmemberJoe Caffeine12:03 4 Oct '10  
GeneralRe: thoughts PinmemberSteveM48:36 5 Oct '10  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    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 | Mobile
Web01 | 2.5.120517.1 | Last Updated 5 Oct 2010
Article Copyright 2010 by Steve Marsh
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid