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

A multi-purpose XP Office 2003 Style hover and flat button with container bar

By , 10 Oct 2006
Rate this:
Please Sign up or sign in to vote.
Prize winner in Competition "VB.NET Apr 2005"

Sample Image - lybralibrary592x444.jpg

Introduction

This control (HoverGradientButton) is very easy to use; graphic and chromatic interface results have a great impact. The original idea is from a good article by Victor Boba (thanks Victor!). HoverGradientButton has a lot of properties, but default properties let the programmer to have a full ready-to-use interface with Office 2003 style. The component supports three different styles: HoverNormal, HoverCheck and HoverOption, that make the HoverGradientButton work respectively as normal Button, CheckBox, and RadioButton. The core component HoverGradientButton is shipped with a versatile container (HoverButtonBand) with an additional AutoArrange property.

Furthermore, the library contains GradientPanelXP, a specialized component, inherited from Panel, with some additional features such as Gradient.

Implementation

Just drop HoverGradientButton control on a form, and you are ready to go. Optionally, you can drop HoverGradientButton inside a HoverButtonBand to get additional features and color combinations.

ToolTip is available: place some text on ToolTipText property and set ToolTipActive to True to see ToolTip on the button.

Usage

  • Add the control to the toolbox (LybraVb.dll).
  • Drop the HoverGradientButton on a WinForm or inside a HoverButtonBand.
  • Set the ButtonType property.
  • Select an image for the button.
  • Go!

Points of interest

Both components are written in VB.NET and inherits from Panel. No other additional controls are recursively contained inside the two components. Colors, text and images are drawn with FillRectangle, DrawString and DrawImage methods.

A support class named GS (Graphic Support) controls all the base graphic GDI+ routines.

Here is an example of a Shared method of the GS class:

    Public Shared Function _
    PaintGradientRectangle(ByVal g As Drawing.Graphics, _
                           ByVal aPointX As Integer, _
                           ByVal aPointY As Integer, _
                           ByVal aWidth As Integer, _
                           ByVal aHeight As Integer, _
                           ByVal aColor1 As Color, _
                           ByVal aColor2 As Color, _
                           ByVal aGradientMode As _
                                 Drawing2D.LinearGradientMode) _
                           As RectangleF

      Dim RectanglePaint As RectangleF = GS.XRectangleF(aPointX, _
                                          aPointY, aWidth, aHeight)
      Dim gradBrush As New _
          System.Drawing.Drawing2D.LinearGradientBrush(RectanglePaint, _
          aColor1, aColor2, aGradientMode)
      g.FillRectangle(gradBrush, RectanglePaint)
      Return RectanglePaint
    End Function

and here is an example of the use of the GS class and its shared methods:

      'Paint the rectangle
      GS.PaintGradientRectangle(e.Graphics, 0, 0, Me.Width, Me.Height, _
                                            c1, c2, mGradientMode)


      'Draw the image
      e.Graphics.DrawImage(mImage, p.X, p.Y, mImage.Width, mImage.Height)

      'Write the text
      GS.WriteText(e.Graphics, Me.Text, Me.Font, _
                  Me.TextAlign, _
                  mTextQuality, _
                  Me.ForeColor, _
                  0, 0, Me.Width, Me.Height)

      'Draw the border
      GS.PaintBorder(e.Graphics, 0, 0, Me.Width, Me.Height, cb)

The AutoArrange property of HoverButtonBand works at design time, even while the control is resized. This is achieved with a specifically designed Friend class (ButtonsReorder).

This is the ButtonsReorder class:

    Friend Class AlignButtons

      Public Sub New()
      End Sub

      Public Shared Sub _
             ButtonsReorder(ByRef aObjects As _
                            System.Windows.Forms.Control.ControlCollection, _
                            ByVal rType As HowReorder, _
                            ByVal rAlign As HowAlign, _
                            Optional ByVal iMargin As Integer = 0, _
                            Optional ByVal iSpacer As Integer = 0)

        If aObjects.Equals(Nothing) Then Exit Sub
        If aObjects.Count = 0 Then Exit Sub

        Dim CountOfControls As Integer = aObjects.Count

        Dim cContainer As Control = CType(aObjects.Item(0), Control).Parent
        Dim WidthOfContainer As Integer = cContainer.Width
        Dim HeightOfContainer As Integer = cContainer.Height
        Dim WidthOfControlli As Integer = 0
        Dim HeightOfControlli As Integer = 0

        Dim o As Control
        For Each o In aObjects
          WidthOfControlli += o.Width
          HeightOfControlli += o.Height
        Next

        Dim VariablePosition As Integer = 0
        Dim FixedPosition As Integer = 0

        Select Case rType
          Case HowReorder.Horizontal
            VariablePosition = iMargin
            FixedPosition = Convert.ToInt32((HeightOfContainer - o.Height) / 2)
            For Each o In aObjects
              o.Left = VariablePosition
              o.Top = FixedPosition
              If rAlign = HowAlign.Center Then 
                  iSpacer = Convert.ToInt32((WidthOfContainer - _
                            WidthOfControlli - iMargin) / (CountOfControls + 1))
              VariablePosition = VariablePosition + iSpacer + o.Width
            Next
          Case HowReorder.Vertical
            VariablePosition = iMargin
            FixedPosition = Convert.ToInt32((WidthOfContainer - o.Height) / 2)
            For Each o In aObjects
              o.Top = VariablePosition
              o.Left = FixedPosition
              If rAlign = HowAlign.Center Then
                  iSpacer = Convert.ToInt32((HeightOfContainer - _
                            HeightOfControlli - iMargin) / (CountOfControls + 1))
              VariablePosition = VariablePosition + iSpacer + o.Width
            Next
        End Select

      End Sub

    End Class

The HoverButtonBand container can fully control the position of the buttons vertically or horizontally. This is very interesting. This is achieved with the properties AutoArrange, AutoArrangeDirection, AutoArrangeAlignment, AutoArrangeButtonSpace, and AutoArrangMargin.

The graphic look

As it's noticeable, I've put particular attention to the graphic and chromatic appearance of the controls. I think I reached a good result. As part of the properties dedicated to the graphic look of the controls, for example, I've implemented a new property (TextQuality) that allows you to set the way the texts are drawn. TextQuality can be set as SystemDefault, AntiAlias or ClearType. Changing these settings to AntiAlias or ClearType can lightly reduce drawing speed, but the result is great.

HoverGradientButton main properties

  • ButtonType

    Enum. Use HoverNormal for using as normal flat Button. Use HoverCheck for use as CheckBox. Use HoverOption for use as RadioButton.

  • OptionGroup

    Integer. When ButtonType is equal to RadioButton this number indicates the group of alternative options inside a group of options.

  • BackColor1 and BackColor2

    Color. The first and the second color of the button (gradient colors) when the mouse is not over the control.

  • HoverColor1 and HoverColor2

    Color. The first and the second color of the button (gradient colors) when the mouse is over the control.

  • SelectedColor1 and SelectedColor2

    Color. The first and the second color of the button (gradient colors) when the control is selected (ButtonType, HoverCheck or HoverOption) and mouse is not over the control.

  • SelectedHoverColor1 and SelectedHoverColor2

    Color. The first and the second color of the button (gradient colors) when the control is selected (ButtonType, HoverCheck or HoverOption) and mouse is over the control.

  • ClickColor1 and ClickColor2

    Color. The first and the second color of the button (gradient colors) when the mouse is clicked on the control.

  • Image

    Image. The image drawn on the button.

  • ImageSelected

    Image. The image drawn on the button when the control is selected (ButtonType, HoverCheck or HoverOption).

  • HoverForeColor

    Color. Color of the text when the mouse is over the control.

  • Selected

    Boolean. The value of the button when the control is selected (ButtonType, HoverCheck or HoverOption).

  • OptionGroup

    Integer. The group of the button when ButtonType property is HoverOption.

  • ToolTipActive

    Boolean. Indicates if ToolTip is active or not.

  • ToolTipText

    String. The text displayed as ToolTip when the cursor is over the button.

HoverButtonBand main properties

  • BackColor1 and BackColor1

    Color. The first and the second color (gradient colors) of the container (Band).

  • AutoArrange

    Boolean. Controls if the contained buttons are to be automatically aligned or not.

  • AutoArrangeDirection

    Enum. Horizontal or Vertical. Controls the direction of the alignment.

  • AutoArrangeAlignment

    Enum. Controls the alignment of the contained buttons. Can be Center or LeftOrTop (depends on the direction determined by AutoArrangeDirection).

  • AutoArrangeButtonSpace

    Integer. The distance between the contained buttons.

  • AutoArrangeMargin

    Integer. The margin of the group of buttons.

Using the controls

As mentioned above, the use of the controls is very easy and intuitive. You can also use the HoverGradientButton and the HoverButtonBand as stand-alone controls. However, I suggest to use them together. Please note that the best graphical effect is reached with a button size of 24x24 containing a 16x16 image, or a button size of 40x40 containing a 32x32 image (if you plan to use no text). A HoverButtonBand width (or height for vertical placement) same as the inner HoverGradientButton will give you the best graphical and chromatic effect. I strongly suggest use of PNG images instead of ICO or BMP, and avoiding use of multiformat icons.

Using HoverGradientButton as CheckBox

Setting ButtonType=HoverCheck will make HoverGradientButton act as a CheckBox. When it is checked, the Selected property becomes True and the image changes (if you set an image to ImageSelected property). The control remains selected until the button is clicked again.

Using HoverGradientButton as RadioButton

Setting ButtonType=HoverOption will make HoverGradientButton act as a RadioButton. When it is checked, the Selected property becomes True and the image changes (if you set an image to ImageSelected property). All other controls having the same OptionGroup property lose the selected state (Selected=False) and the color is set back to BackColor1 and BackColor2.

This is how ButtonType=HoverCheck and ButtonType=HoverOptions are managed by the code:

    Private Sub HoverGradientButton_Click(ByVal sender As Object, _
                ByVal e As System.EventArgs) Handles MyBase.Click

      If mButtonType = HoverButtonType.HoverNormal Then Exit Sub
      If mButtonType = HoverButtonType.HoverOption Then
        If Not mSelected Then
          mSelected = True
          'Uncheck other buttons
          ClearOptionButtons.Clear(Me)
        End If
      Else
        mSelected = Not mSelected
      End If

    End Sub

IButtonControl interface

The IButtonControl interface allows HoverButtonBar to work as a conventional button. A control that implements the IButtonControl interface is recognized, for example, by the AcceptButton and CancelButton properties of a Form. Now HoverButton implements correctly the IButtonCommand interface.

Known problems

The only problem I know is the order of the buttons during automatic arrange inside the HoverButtonBar. Sometimes, one of the buttons goes to an apparently random position. This is because I actually don't have the full control of buttons order inside the HoverButtonBar ControlsCollection. Please drop me a line if you have some suggestions in order to solve this.

The future, the present

HoverButton and related controls has become part of a huge project called Naxos Development.

History

  • May 24, 2005 - Original version (1.0)
  • May 30, 2005 - Version 1.1
    • HoverGradientButton is no longer a container.
    • HoverGradientButton no longer displays grid at design time.
    • Added GradientMode to HoverButtonBand and HoverGradientButton.
    • Added TextQuality property to HoverButtonBand and HoverGradientButton.
    • Improved drawing speed.
    • Added class GS (Graphic Support) with shared methods for common GDI+ routines.
  • June 6, 2005 - Version 1.1.7
    • Added GradientPanelXP component.
    • Minor enhancements and small bug fixes.
  • June 21, 2005 - Version 1.2.0
    • Added ToolTip feature to the button.
  • October, 7, 2006 - Version 1.3.1
    • Changed base class (from Panel to Control); more lightweight now.
    • If Enabled = False now Text and Image are correctly disabled (Enrico Detoma suggestion, thanks).
    • Implemented IButtonControl interface (merlin.AT suggestion, thanks).
    • Fixed ButtonsReorder error with vertical HowRedorder.Vertical (RichardJMoss suggestion, thanks).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

carloqueirolo
Web Developer
Italy Italy
Carlo Queirolo, 45 years old, MCP, living with Antonella and father of Tommaso
(Thomas), is a eighteen-years-experienced entreprise programmer. He was born in
Genoa (Italy) and now he lives in Milan (Italy). Carlo mainly works for client-server
and database development. Feel free to reach Carlo at carlodevREMOVE@gmail.com.
Currently, he's looking for a job or contract (everywhere).
 
My .NET web site
 

Comments and Discussions

 
Generallybralibrary.dll PinmemberutksThedeveloper30-Mar-07 0:39 
GeneralError in OnPaint (v1.3.1) PinmemberNicoS9-Mar-07 6:02 
QuestionSeparators PinmemberMember #243136628-Feb-07 23:36 
GeneralTooltipText doesn't work Pinmemberkevinlkingma10-Feb-07 4:30 
GeneralGreat work, but a question PinmemberZaegra14-Jan-07 3:06 
GeneralALT + TEXT PinmemberMerlinCM6-Dec-06 11:52 
GeneralUse as a navigation bar Pinmemberkevinlkingma22-Nov-06 10:11 
GeneralRe: Use as a navigation bar Pinmembercarloqueirolo22-Nov-06 21:34 
Generalsupport of tabstop+image problem PinmemberAsif Rehman24-Oct-06 1:01 
GeneralRe: support of tabstop+image problem Pinmembercarloqueirolo24-Oct-06 1:35 
GeneralImageSelected Property: Looks Not working PinmemberSameers (theAngrycodeR )19-Oct-06 8:08 
GeneralRe: ImageSelected Property: Looks Not working PinmemberSameers (theAngrycodeR )19-Oct-06 9:43 
GeneralRe: ImageSelected Property: Looks Not working Pinmembercarloqueirolo24-Oct-06 1:23 
AnswerRe: ImageSelected Property: Looks Not working PinmemberSameers (theAngrycodeR )24-Oct-06 7:19 
GeneralBug: Panel Scrolling PinmemberSourSW2-Jun-06 6:27 
GeneralRe: Bug: Panel Scrolling Pinmembercarloqueirolo13-Jun-06 9:51 
QuestionImage Disappears Pinmembertheukjock28-Apr-06 23:24 
AnswerRe: Image Disappears Pinmembercarloqueirolo29-Apr-06 8:35 
GeneralRe: Image Disappears Pinmembertheukjock29-Apr-06 9:09 
GeneralRe: Image Disappears Pinmembercarloqueirolo29-Apr-06 21:26 
AnswerRe: Image Disappears PinmemberEx M.A.Tech18-Aug-06 18:46 
QuestionAcceptNutton Pinmembermerlin.AT8-Apr-06 23:14 
AnswerRe: AcceptNutton Pinmembercarloqueirolo18-Apr-06 21:55 
GeneralFree Use Pinmemberbsilva30-Mar-06 5:41 
GeneralRe: Free Use Pinmembercarloqueirolo30-Mar-06 19:47 
GeneralVertical alignment PinmemberRichardJMoss16-Jan-06 5:52 
GeneralRe: Vertical alignment Pinmembercarloqueirolo30-Mar-06 19:49 
GeneralVery nice + small suggestion PinmemberEnrico Detoma15-Jan-06 12:02 
GeneralRe: Very nice + small suggestion Pinmembercarloqueirolo30-Mar-06 19:52 
GeneralSuperb and Professional PinmemberOakman23-Nov-05 12:36 
GeneralRe: Superb and Professional Pinmembercarloqueirolo14-Jan-06 6:14 
GeneralButton Not working in DataBase PinmemberNickJS2-Nov-05 13:31 
AnswerRe: Button Not working in DataBase Pinmembercarloqueirolo2-Nov-05 22:52 
GeneralNot working for MDI application Pinmemberanu_kgec21-Oct-05 1:54 
GeneralRe: Not working for MDI application Pinsusscarloqueirolo21-Oct-05 4:38 
GeneralRe: Not working for MDI application Pinmemberanu_kgec22-Oct-05 2:06 
GeneralVery Nice Work Pinmemberanu_kgec22-Oct-05 2:13 
GeneralRe: Very Nice Work Pinmembercarloqueirolo22-Oct-05 2:28 
GeneralC# PinmemberSk8tz19-Sep-05 20:34 
GeneralRe: C# Pinmembercarloqueirolo20-Sep-05 23:54 
QuestionRe: C# PinmemberSk8tz21-Sep-05 2:31 
AnswerRe: C# Pinmembercomputerguru9238223-Sep-05 17:25 
GeneralImages PinmemberStephenMcAllister4-Sep-05 22:48 
GeneralRe: Images Pinmembercarloqueirolo4-Sep-05 23:00 
GeneralVery Nice PinmemberStewBob1-Jul-05 6:05 
GeneralRe: Very Nice Pinmembercarloqueirolo1-Jul-05 6:30 
GeneralGreat work PinmemberAlessio.NET29-Jun-05 4:50 
GeneralRe: Great work Pinmembercarloqueirolo29-Jun-05 4:58 
GeneralRe: Great work Pinmembercomputerguru9238223-Sep-05 17:26 
GeneralRe: Great work Pinsusscarloqueirolo26-Sep-05 4:58 

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.140415.2 | Last Updated 10 Oct 2006
Article Copyright 2005 by carloqueirolo
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid