Click here to Skip to main content
Click here to Skip to main content

gLabel - Custom Label with Special Effects (VB.NET)

, 5 Jan 2012
Rate this:
Please Sign up or sign in to vote.
Label control with built-in effects like MouseOver, Shadow, Outer Glow, and Pulse Glow.
Prize winner in Competition "Best VB.NET article of July 2010"

gLabel.png

Introduction

I had been working on a custom label control that had a built-in shadow, so I didn't have to layer separate labels or draw text multiple times to a Graphics object. After reading Wong Shao Voon's outstanding article Outline Text [^], I knew I found exactly what I needed. The simplicity of just layering ever widening Pens to get the glow effect was great. I would love to implement more of his ideas someday, but haven't had time to convert it to VB.NET yet. Someday...

As usual with me, what was a simple control to fill a need in the beginning kept growing as I thought of all the what if's. The static outline/shadow label gains a clickable mouseover option which expands to a pulsing alternative to the marquee progress bar...

What is the gLabel? In simple terms, it is an extended Label or in other words, a custom control that inherits Label and overrides the OnPaint event to give it a brand new paint job.

Features:

  • Solid or blended fill color
  • Outline text
  • Outer glow highlighting
  • MouseOver glow color
  • Pulsing glow option
  • Text shadow
  • AutoFit
  • CheckBox and RadioButton behavior option

Control Properties

Here is a list of the primary properties:

  • AutoFit
  • If True, the text to the bounds of the control; False uses font size to paint text

  • BackColor, Border, BorderColor, BorderWidth
  • Handle the appearance of the background box area

  • FillType
  • Use solid color or a custom blend of colors

  • FillTypeLinear
  • What type of gradient fill to apply

  • ForeColor, ForeColorBlend
  • Color or Colors to paint the actual text

  • Glow
  • How far to extend the glow color out from the text

  • GlowColor, GlowState
  • What color to Glow if the GlowState is true

  • FeatherState
  • If FeatherSate is True, fade the glow color

  • Feather
  • How intense to make the glow color

  • MouseOver, MouseOverColor
  • If MouseOver is true, what color to paint the glow

  • Pulse, PulseSpeed
  • If Pulse is true, fade the GlowColor in and out

  • ShadowState, ShadowColor, ShadowOffset
  • If ShadowState is true, paint a shadow to the offset

UITypeEditor

ForeColorBlend uses the custom BlendTypeEditor. See UITypeEditorsDemo[^] for a detailed explanation of UITypeEditors and ControlDesigners.

Using the gLabel

Drop a gLabel on your Form just like a normal Label. AutoSize is hidden, so size the control to fit the FontSize or set AutoFit to True to make the text fit the control.

Points of Interest

First the transparent background behaves just like a standard Label control. I tried using the true transparent background method with Protected Overrides ReadOnly Property CreateParams(), but the flickering was horrendous, so I removed it.

On to what does work. As with any control, the painting consists of a series of layers. The first of course is the background. This takes place in the Protected Overrides Sub OnPaintBackground event. If BackColor is Transparent, then let the MyBase handle it. Otherwise I get the background color according to its Enabled state.

Protected Overrides Sub OnPaintBackground( _
    ByVal pevent As System.Windows.Forms.PaintEventArgs)
        
    If Me.BackColor = Color.Transparent Then
        MyBase.OnPaintBackground(pevent)
    Else
        pevent.Graphics.Clear(EnabledColor(Me.BackColor))
    End If
End Sub

The rest of the layers are in the Protected Overrides Sub OnPaint event and will paint based on the state properties for each.

Before I start on the paint layers, let me explain the Glow process first since it is used more than once here.

Glow

The Glow is a gradient that follows the outline of the letters. The gradient is dark close to the letter's edge and gets lighter as it gets further away. In the Color structure ARGB, the A is the Alpha value or how much you can see through it. The value ranges from 0 to 255, with 0 being totally transparent and 255 being a solid color you cannot see through.

If you paint a square in one color like Color.FromARGB(125, Color.Red) and then overlap part of it with another square painted in Color.FromARGB(125, Color.Blue), the parts that do not overlap will be a light red or blue. The parts that do overlap will mix to become purple and more opaque. Now do the same using the same color for both squares. The overlap is blue and the other parts are light blue and more translucent.

AlphaBlend1.png

Now let's look at 6 blue rectangles, each one wider than the last. When you line up the left edges, it makes a gradient like blend from dark to light.

AlphaBlend2.png

Take this one step further by making each successive rectangle a little more transparent than the last and it looks even better.

AlphaBlend3.png

Use this idea with a Pen, where the width of the rectangle corresponds to the width of a Pen. Using the GraphicsPath of a String, loop the number of times you want to create the glow effect. Then fill the path at the end to create the face of the text.

For i As Integer = 1 To _Glow Step 2
    Dim aGlow As Integer = CInt(_Feather - _
      ((_Feather / _Glow) * i))
    Using pen As Pen = New Pen(Color.FromArgb( _
      aGlow, EnabledColor(gColor)), i)
        pen.LineJoin = LineJoin.Round
        g.DrawPath(pen, path)
    End Using
Next i

g.FillPath(New SolidBrush(Me.ForeColor), path)

OnPaint

OK, back to the layers. First, to paint the shadow, I get a GraphicsPath for the text and use a Matrix to Translate the (X, Y) coordinates by the ShadowOffset property. Then paint the shadow using the above Glow process.

Next is the actual glow text. Determine the glow color based on the MouseOver properties. Use the above Glow process, but with these options: FeatherState, Enabled, and Pulse. Lastly, fill the text path using the fill properties.

The last layer is the border which simply draws a rectangle around the gLabel's rectangle area using the border properties.

AutoFit

The standard label has an AutoSize property, but all it does is adjust the width to the text length. I wanted the text to fill the area. To fit a text path to the size of the control, I use a Matrix to transform the GraphicsPath.

Let's look at when you need to fit a label within a specific area. Long text in a standard Label will get cut off. Reducing the Font.Size to make the text fit sometimes makes the height too small to read well. Fitting the text squeezes the width independently of the height.

LongText.png

To do this, first make a Rectangle of the area you want the text to fit inside.

Dim target As New Rectangle( _
    0, 0, _
    Me.ClientSize.Width, _
    Me.ClientSize.Height)

Then get a PointF representation of the target rectangle.

Dim target_pts() As PointF = { _
    New PointF(target.Left, target.Top), _
    New PointF(target.Right, target.Top), _
    New PointF(target.Left, target.Bottom) _
    }

Use the GraphicsPath AddString to get a path of the text close to the size of the target rectangle. Then use GetBounds to get the rectangle around the path.

path.AddString(Me.Text, Me.Font.FontFamily, Me.Font.Style, _
               target.Height, New PointF(0, 0), sf)
Dim text_rectf As RectangleF = path.GetBounds() 

Then use a Matrix to Transform the Graphics object to fit the text to the target rectangle.

g.Transform = New Matrix(text_rectf, target_pts)

To pulse the GlowColor, a Timer is used to increase and decrease the Feather value.

Private Sub Pulser_Tick(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Pulser.Tick
    _PulseAdj += PulseDirection
    If _Feather - _PulseAdj < 10 _
      OrElse _Feather - _PulseAdj > _Feather Then
        PulseDirection *= -1
        _PulseAdj += PulseDirection
    End If
    Me.Invalidate()
End Sub

TypeConverter for ColorFillBlend

New in Version 1.0.8, a TypeConverter for the ForeColorBlend can convert a String representation of the blend to a cBlendItems to allow more precise tweaking and to easily copy a blend from one gLabel to another.

CheckType: CheckBox and RadioButton Behaviors

The CheckType property can be set as Label, Check, or Radio. Label behaves like a standard label when clicked. Check sets the Checked property and colors independent of the other gLabels when clicked. Radio sets the Checked property to True and sets all other gLabels set to type Radio to False on the same parent.

When the GlowMatchChecked property is True, the GlowState will change with the Checked property.

Fancy label done.

History

  • Version 1.0.5 - July 2010
    • First published version
  • Version 1.0.6 - January 2011
    • Added padding support
    • Added TextWordWrap property
    • Added AutoEllispis support
  • Version 1.0.7 - March 2011
    • Added MouseOverForeColor property
    • Added Checked property
    • Added CheckedColor property
    • Added CheckedToggleState method
  • Version 1.0.8 - January 2012
    • Added BlendItemsConverter
    • Cleaned up default Values
    • Added CheckedType property

License

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

About the Author

SSDiver2112
Software Developer
United States United States
I first got hooked on programing with the TI994A. After it finally lost all support I reluctantly moved to the Apple IIe. Thank You BeagleBros for getting me through. I wrote programs for my Scuba buisness during this time. Currently I am a Database manager and software developer. I started with VBA and VB6 and now having fun with VB.NET

Comments and Discussions

 
GeneralMy vote of 1 PinmemberNathan Ferreira9-Jul-14 3:13 
GeneralRe: My vote of 1 PinpremiumSSDiver211210-Jul-14 15:57 
QuestionLove this control. PinmemberWilliam Vincent24-Mar-14 6:59 
QuestionChange font? PinmemberMember 1033427417-Jan-14 21:11 
AnswerResolved PinmemberMember 1033427427-Jan-14 12:59 
QuestionWhere is the dll? Pinmemberpamoxi22-Nov-13 2:06 
AnswerRe: Where is the dll? PinmemberSSDiver211222-Nov-13 5:39 
GeneralRe: Where is the dll? Pinmemberpamoxi22-Nov-13 5:52 
QuestionCrashes apps compiled for x86 PinmemberMember 1033427414-Oct-13 13:47 
AnswerRe: Crashes apps compiled for x86 PinmemberMember 1033427415-Oct-13 17:54 
GeneralRe: Crashes apps compiled for x86 PinmemberSSDiver211216-Oct-13 10:26 
GeneralRe: Crashes apps compiled for x86 PinmemberMember 103342744-Nov-13 19:02 
GeneralThanks! PinmemberMember 101790899-Sep-13 8:29 
QuestionAutofit doesn' function when gLabel created programmatically Pinmemberdherrmann29-Aug-13 21:36 
AnswerRe: Autofit doesn' function when gLabel created programmatically PinmemberSSDiver211230-Aug-13 4:33 
GeneralRe: Autofit doesn' function when gLabel created programmatically Pinmemberdherrmann30-Aug-13 21:59 
QuestionMouseOver PinmemberN. Henrik Lauridsen11-Jun-13 23:23 
AnswerRe: MouseOver PinmemberSSDiver211221-Jul-13 10:00 
GeneralRe: MouseOver PinmemberN. Henrik Lauridsen24-Jul-13 2:29 
QuestionBookmarked !T PinmemberGun Gun Febrianza16-Oct-12 16:01 
GeneralMy vote of 5 PinmemberGun Gun Febrianza16-Oct-12 16:01 
QuestionAbsolutely Fantastic Pinmemberlspogson11-Sep-12 10:38 
GeneralMy vote of 5 PinmemberPolinia4-Sep-12 3:05 
QuestiongLabel Pinmembersutr6930-Aug-12 1:56 
GeneralMy vote of 5 PinmemberJohn Espiritu19-Aug-12 16:07 
Question!urgent! Pinmemberschematicsman10-Jul-12 15:09 
QuestionIssue with label and forms Pinmemberalexamex21-Apr-12 11:00 
AnswerRe: Issue with label and forms PinmemberSSDiver211224-Apr-12 4:35 
QuestionVisual Studio 2010? PinmemberMark Kram27-Mar-12 8:32 
AnswerRe: Visual Studio 2010? PinmemberSSDiver211227-Mar-12 9:06 
GeneralRe: Visual Studio 2010? PinmemberMark Kram27-Mar-12 13:30 
QuestionDraw gLabel onto an image PinmemberThe4runner8-Mar-12 9:23 
AnswerRe: Draw gLabel onto an image PinmemberSSDiver21128-Mar-12 9:39 
GeneralRe: Draw gLabel onto an image PinmemberThe4runner9-Mar-12 4:15 
GeneralRe: Draw gLabel onto an image PinmemberSSDiver21129-Mar-12 5:40 
GeneralMy vote of 5 Pinmembermanoj kumar choubey24-Feb-12 2:47 
GeneralMy vote of 5 PinmemberPaul van der Stel29-Jan-12 4:18 
Questionawesome PinmemberCuddlesLapine27-Jan-12 7:21 
GeneralMy vote of 5 PinmemberJustJimBean9-Jan-12 18:14 
GeneralRe: My vote of 5 PinmemberSSDiver211210-Jan-12 2:15 
QuestionWinform and/or WPF Pinmemberrctaubert6-Jan-12 2:38 
AnswerRe: Winform and/or WPF PinmemberSSDiver21126-Jan-12 3:47 
GeneralMy vote of 5 PinmemberJavedsamrt4-Jan-12 2:50 
GeneralJust what I needed PinmemberGunze21-Dec-11 22:28 
GeneralRe: Just what I needed PinmemberSSDiver211222-Dec-11 4:12 
GeneralMy vote of 5 Pinmembertaony6-Sep-11 17:12 
QuestionRotation angle PinmemberMember 312843722-May-11 22:45 
AnswerRe: Rotation angle PinmemberSSDiver211225-May-11 2:47 
GeneralMy vote of 5 PinmemberАslam Iqbal23-Mar-11 22:44 
QuestionPadding? PinmemberBobishKindaGuy3-Feb-11 9:27 

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.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 5 Jan 2012
Article Copyright 2010 by SSDiver2112
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid