Click here to Skip to main content
6,595,444 members and growing! (21,350 online)
Email Password   helpLost your password?
Desktop Development » Button Controls » General     Intermediate License: The Code Project Open License (CPOL)

Custom Button Control with Gradient Colors and Extra Image (VB.NET)

By SSDiver2112

This is a simple to use custom button control, but with a lot of visual design options.
VB, Windows, .NET 2.0, GDI+, Dev
Posted:3 Jun 2008
Updated:24 Dec 2008
Views:52,264
Bookmarked:87 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
35 votes for this article.
Popularity: 6.95 Rating: 4.50 out of 5
1 vote, 2.9%
1
1 vote, 2.9%
2
3 votes, 8.6%
3
3 votes, 8.6%
4
27 votes, 77.1%
5

Introduction

The CButton is a simple custom button control written in VB.NET. Sorry I didn't realize the "C" prefix was a language specific thing when I started. It is just short for Custom Button. I won't let it happen again. This is a great alternative to the plain Microsoft button.

Here is a list of the primary features:

  1. Change the Shape of the button
  2. Adjust the corners of a round rectangle
  3. Solid and Multi color Fills
  4. Text shadow and margin
  5. Adjustable rollover and click color change with simulated click movement
  6. Normal button image and/or additional sideimage

I improved design time editing in Version 1.2 by adding UITypeEditors and ControlDesigners. See UITypeEditorsDemo[^] for a detailed explanation. This enabled me to combine some properties into one single property, or improve on others.

For example:

  • ButtonColorA, ButtonColorB, and ButtonColorC were combined into ColorFillBlend allowing unlimited Color blend instead of being limited to only three colors
  • ButtonColorCenterPoint, and ButtonColorCenterPtOffset were combined into FocalPoints
  • CornerRadius became an expandable property Corners allowing each corner to be adjusted separately

Background

Here is another example of needing (well, let's be honest, a plain button would work, so I wanted) a better looking and visually versatile button. There are a lot of great button controls already, but not with all the features I was looking for. Basically, I created the properties I was looking for, and then took over the OnPaint to draw it the way I wanted.

Control Properties

Here is a list of the primary properties:

  • Shape

    What shape the button is (Rectangle, Ellipse, Triangle)

  • ColorFillBlend

    Colors to use in gradient blend fills

  • BorderColor, BorderShow

    Show the border in a different color

  • FillType

    What color gradient type to use (Solid, Linear, or Path)

  • FocalPoints

    CenterPoint and FocusScales for Path Gradient Type Fills

  • Corners

    Radius for each corner arc

  • DimFactorHover, DimFactorClick

    Number to adjust the buttons color during mouse rollover and click

  • TextShadow, TextShadowShow

    Show or not show the shadow of the text and in what color

  • TextMargin

    Push the text away from the inside edge of the button

  • SideImage

    Add an extra image that can be placed outside the button surface

  • Padding

    Offset the edges of the ButtonArea from the edge of the Control

Using the Code

Once you get the CButton designed the way you want, there isn't really any complicated code. Just use it like a normal button.

Because the Click event fires if you click anywhere on the control, I added the ClickButtonArea event in Version 1.1 to fire only when the mouse clicks inside the button part of the control.

'Add a new Click event for only when the ButtonArea is Clicked
Public Event ClickButtonArea(ByVal Sender As Object, ByVal e As EventArgs)

Private Sub CButton_MouseUp(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
    If MouseDrawState = eMouseDrawState.Down _
        Then RaiseEvent ClickButtonArea(Me, New EventArgs)
    MouseDrawState = eMouseDrawState.Up
    Me.Invalidate(ButtonArea)
End Sub

Points of Interest

The control is just a process of layering the parts together in the right positions. There are four main areas to track. The control area, button area, text area, and image area. The button area is reduced from the control area by the control padding values. The text area is reduced from the button area by the text margin values and the image area. The image area is based on the image size. The items are placed into these areas based on their layout options.

Protected Overrides Sub _
    OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

    'Gray the Text and Border Colors if Disabled
    Dim bColor, tColor, tsColor As Color
    If Me.Enabled Then
        bColor = _BorderColor
        tColor = Me.ForeColor
        tsColor = _TextShadow
    Else
        bColor = GrayTheColor(_BorderColor)
        tColor = GrayTheColor(Me.ForeColor)
        tsColor = GrayTheColor(_TextShadow)
    End If

    Dim MyPen As New Pen(bColor)
    MyPen.Alignment = PenAlignment.Inset

    'Shrink the Area so the Border draws correctly, _
    'then trim off the Padding to get the button surface area
    ButtonArea = AdjustRect(New Rectangle(0.5, 0.5, _
        Me.Size.Width - 1, Me.Size.Height - 1), Me.Padding)

    'Create the ButtonArea Path
    Dim gp As GraphicsPath = GetPath()

    If Me.BackgroundImage Is Nothing Then

        'Color the ButtonArea with the right Brush
        Select Case Me.FillType
            Case eFillType.Solid
                Using br As Brush = New SolidBrush(GetFill)
                    e.Graphics.FillPath(br, gp)
                End Using

            Case eFillType.GradientPath
                Using br As PathGradientBrush = New PathGradientBrush(gp)
                    Dim cb As New ColorBlend
                    cb.Colors = GetFillBlend()
                    cb.Positions = Me.ColorFillBlend.iPoint

                    br.FocusScales = FocalPoints.FocusScales
                    br.CenterPoint = New PointF( _
                        Me.Width * FocalPoints.CenterPoint.X, _
                        Me.Height * FocalPoints.CenterPoint.Y)
                    br.InterpolationColors = cb

                    e.Graphics.FillPath(br, gp)
                End Using

            Case eFillType.GradientLinear
                Using br As LinearGradientBrush = New LinearGradientBrush( _
                  ButtonArea, Color.White, Color.White, FillTypeLinear)
                    Dim cb As New ColorBlend
                    cb.Colors = GetFillBlend()
                    cb.Positions = Me.ColorFillBlend.iPoint

                    br.InterpolationColors = cb

                    e.Graphics.FillPath(br, gp)
                End Using

        End Select
    End If

    If BorderShow Then
        e.Graphics.DrawPath(MyPen, gp)
    End If
    gp.Dispose()

    Dim ipt As Point = ImageLocation(GetStringFormat(Me.SideImageAlign), _
        Me.Size, Me.SideImageSize)

    'Put the SideImage behind the Text
    If SideImageBehindText AndAlso Me.SideImage IsNot Nothing Then
        e.Graphics.DrawImage(EnableDisableImage(Me.SideImage), ipt.X, ipt.Y, _
            Me.SideImageSize.Width, Me.SideImageSize.Height)
    End If

    'Layout the Text and Image on the button surface
    SetImageAndText(e.Graphics)

    If Not Me.Image Is Nothing Then
        e.Graphics.DrawImage(EnableDisableImage(Me.Image), Imagept.X, Imagept.Y, _
            Me.ImageSize.Width, Me.ImageSize.Height)
    End If

    'Draw the Text and Shadow
    If TextShadowShow Then
        TextArea.Offset(1, 1)
        e.Graphics.DrawString(Me.Text, Me.Font, _
            New SolidBrush(tsColor), TextArea, GetStringFormat(Me.TextAlign))
        TextArea.Offset(-1, -1)
    End If
    e.Graphics.DrawString(Me.Text, Me.Font, _
        New SolidBrush(tColor), TextArea, GetStringFormat(Me.TextAlign))

    'Put the SideImage in front of the Text
    If Not SideImageBehindText AndAlso Not Me.SideImage Is Nothing Then
        e.Graphics.DrawImage(EnableDisableImage(Me.SideImage), ipt.X, ipt.Y, _
            Me.SideImageSize.Width, Me.SideImageSize.Height)
    End If

    MyPen.Dispose()
End Sub

To Gray the colors when the control is disabled, I used two methods:

To Gray a single color, I used this Function:

Function GrayTheColor(ByVal GrayColor As Color) As Color
   Dim gray As Integer = _
	CInt(GrayColor.R * 0.3 + GrayColor.G * 0.59 + GrayColor.B * 0.11)
   Return Color.FromArgb(GrayColor.A, gray, gray, gray)
End Function

To Gray an Image, I used this Function:

Private Function EnableDisableImage(ByVal img As Image) As Bitmap
    If Me.Enabled Then Return img
    Dim bm As Bitmap = New Bitmap(img.Width, img.Height)
    Dim g As Graphics = Graphics.FromImage(bm)
    Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
         {New Single() {0.5, 0.5, 0.5, 0, 0}, _
        New Single() {0.5, 0.5, 0.5, 0, 0}, _
        New Single() {0.5, 0.5, 0.5, 0, 0}, _
        New Single() {0, 0, 0, 1, 0}, _
        New Single() {0, 0, 0, 0, 1}})

    Dim ia As ImageAttributes = New ImageAttributes()
    ia.SetColorMatrix(cm)
    g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, _
        img.Width, img.Height, GraphicsUnit.Pixel, ia)
    g.Dispose()
    Return bm

End Function

FocalPoints

New in Version 1.5, when the FillType is GradientPath a small square and circle selection will appear on the control. Drag the circle around to move the CenterPoint, and drag the square to move the FocusScales. Check out the UITypeEditorsDemo link above to see an explanation of this feature.

History

  • Version 1.0 - May 2008
  • Version 1.1 - July 2008
    • Updated "Clickable Region" and added a ClickButtonArea event
  • Version 1.2 - September 2008
    • Updated Properties to use UITypeEditors and ControlDesigner
    • Added Triangular Buttons
  • Version 1.3 - September 2008
    • Button Area Click Fix. The button did not click when the mouse was moving
  • Version 1.4 - October 2008
    • Added Enable/Disable Feature
  • Version 1.5 - December 2008
    • Fixed the FocalPoints and Corners properties to immediately refresh the control when the child properties are changed in the PropertyGrid
    • Removed FocalPoints Modal UITypeEditor and added direct adjustment of the points on the design surface

License

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

About the Author

SSDiver2112


Member
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
Occupation: Software Developer
Location: United States United States

Other popular Button Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 32 (Total in Forum: 32) (Refresh)FirstPrevNext
NewsGreat Control! - Added Keyboard Events Pinmembergetholdofphil9:47 6 Nov '09  
QuestionEvent SideImageClick()? PinmemberZephlon12:01 5 Jul '09  
AnswerRe: Event SideImageClick()? PinmemberSSDiver211218:11 26 Aug '09  
Generalchanges from CButton to MyButton PinmemberLivioCicala8:53 29 May '09  
GeneralRe: changes from CButton to MyButton PinmemberLivioCicala0:01 30 May '09  
Generalradiobuttons and checkboxes Pinmembercwold776:00 21 May '09  
GeneralAdditional Feature PinmemberAtrius10:47 14 Apr '09  
GeneralRe: Additional Feature PinmemberSSDiver211211:40 14 Apr '09  
GeneralRe: Additional Feature PinmemberAtrius12:35 14 Apr '09  
GeneralRe: Additional Feature [modified] PinmemberSSDiver211216:16 14 Apr '09  
GeneralRe: Additional Feature PinmemberAtrius11:29 15 Apr '09  
GeneralRe: Additional Feature PinmemberSSDiver21125:27 16 Apr '09  
GeneralRe: Additional Feature PinmemberAtrius14:26 23 Apr '09  
GeneralVery nice control Pinmembermattskelton7:20 15 Mar '09  
GeneralTransparency color Pinmemberxm.xm6:42 12 Jan '09  
AnswerRe: Transparency color PinmemberSSDiver21127:58 12 Jan '09  
GeneralRe: Transparency color Pinmemberxm.xm8:59 12 Jan '09  
GeneralGreat Control - Made an adjustment you might like to add PinmemberMember 44147119:46 29 Dec '08  
QuestionProbably a stupid question Pinmemberzuurg13:20 26 Nov '08  
AnswerRe: Probably a stupid question PinmemberSSDiver211216:40 26 Nov '08  
GeneralRe: Probably a stupid question PinmemberMaurice Bernhard4:52 27 Jul '09  
GeneralGreat Work! PinmemberPat Tormey1:28 8 Oct '08  
GeneralClicking button causes form to close PinmemberjlkInLeesburg12:41 21 Jul '08  
GeneralRe: Clicking button causes form to close PinmemberSSDiver211212:53 21 Jul '08  
GeneralRe: Clicking button causes form to close PinmemberjlkInLeesburg13:16 21 Jul '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 24 Dec 2008
Editor: Deeksha Shenoy
Copyright 2008 by SSDiver2112
Everything else Copyright © CodeProject, 1999-2009
Web21 | Advertise on the Code Project