Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WinForms VB.NET Picture Hover Button

0.00/5 (No votes)
14 Jan 2005 1  
Hover button with picture and font that changes with MouseOver.

Introduction

This is a hover button/hover control, that allows for a lot of flexibility as far as look and feel is concerned. You can set the location of the text and the image, as well as the image that is shown when the mouse is over the control. The example uses a VB.NET WinForms UserControl as the base for the control. If you're not experienced with building user controls then this is a great place to start. Looking at the guts of this control you'll learn some of the basics such as how to make a control a container for other controls, how to draw on the control using the Graphics class.

Functionality

The control allows you to use it as a button, or just a container, or simply a hover control. The hovering effect is managed by way of a timer. This is more reliable than using the MouseLeave or MouseEnter events. Each of those events may or may not fire depending on the speed of the mouse over the control. So if you do not use a timer for handling the hover effects, you may end up with a control that has the hover effect applied, but it never goes away because the MouseLeave event was never fired.

Capabilities

  • Can be in a selected state with a selected color defined.
  • Text ForeColor can be a specified color on Hover.
  • Image can be defined for Hover effect.
  • Image can be defined for regular, or non-hover effects.
  • Hover color can be defined. So the control's BackColor looks as if it has changed when the mouse is over the control.
  • Set the border color.
  • Define whether to view the border or not.
  • Define a group of buttons by setting the "Group" string value. This will select or unselect all the buttons with the same "Group" value on the current parent container.
  • Select or unselect all the buttons on the same parent container.
  • Position the text wherever you want on the control using the ContentAlignment enumeration as is currently used for the Label control.
  • Position the image anywhere on the control using the ContentAlignment enumeration as is currently used for the Label control.
  • Use the control as a container for other controls.

Construction

Add a UserControl to your project. Set some of the initial Imports statements as well as OPTION STRICT, etc.

Option Strict On
Option Explicit On 

Imports System.ComponentModel
Imports System.ComponentModel.Design

At the top of the class, add some attributes that define how the control operates:

' DefaultEvent("Click"), This sets the default event when double-clicking

'                       the control in design-mode.

' DefaultProperty("Text"), This will set the default

'                       property for the property inspector

'                       in design-mode.

'

' This attribute makes this control a container for

'                       other controls.

' Designer("System.Windows.Forms.Design.ParentControlDesigner, 

                           System.Design", GetType(IDesigner))
'
<DESIGNER("SYSTEM.WINDOWS.FORMS.DESIGN.PARENTCONTROLDESIGNER, 
                  DefaultProperty(?Text?) DefaultEvent(?Click?), 
                  GetType(IDesigner)), _ System.Design?,> _
Public Class PictureHoverButton
    Inherits System.Windows.Forms.UserControl

Next, in Sub New, set the styles for the control. This manages how the control functions specifically in the area of how to draw the control and what it supports:

        ' This draws the control whenever it is resized

        setstyle(ControlStyles.ResizeRedraw, True)

        ' This supports mouse movement such as the mouse wheel

        setstyle(ControlStyles.UserMouse, True)

        ' This allows the control to be transparent

        setstyle(ControlStyles.SupportsTransparentBackColor, True)

        ' This helps with drawing the control so that it doesn't flicker

        Me.SetStyle(ControlStyles.DoubleBuffer _
          Or ControlStyles.UserPaint _
          Or ControlStyles.AllPaintingInWmPaint, _
          True)

        ' This updates the styles

        Me.UpdateStyles()

Override the OnPaint event for the control. This is where the magic happens. This is where your control is your canvas, and you're the artist.

    Protected Overrides Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(pe)
        Dim TopMargin As Integer
        Dim g As Graphics = pe.Graphics
        Dim DrawHover As Boolean

        _HoverRectangle = Nothing
        _HoverRectangle = New Rectangle(0, 0, Me.Width, Me.Height)


        ' The mouse is hovering over the control

        If _HasFocus Then
            If Me.Selected Then
                Dim rec As New Rectangle(0, 0, Me.Width, Me.Height)
                Dim b As New SolidBrush(Me.SelectedColor)
                g.FillRectangle(b, rec)
            Else
                ' Make sure the color is not Nothing, or Empty

                ' which is the equivalent to nothing for a color.

                If Not HoverColor.Equals(Color.Empty) Then
                    Dim rec As New Rectangle(0, 0, Me.Width, Me.Height)
                    Dim b As New SolidBrush(Me.HoverColor)
                    g.FillRectangle(b, rec)
                End If
            End If

            ' Draw the Hover image 

            If Not Me.Selected Then
                DrawHover = True
            End If
        Else
            If Me.Selected Then
                Dim rec As New Rectangle(0, 0, Me.Width, Me.Height)
                Dim b As New SolidBrush(Me.SelectedColor)
                g.FillRectangle(b, rec)
            End If
        End If

        Dim ptImage As Point
        ' Used to hold the dimensions of the current image

        Dim iWidth As Integer
        Dim iHeight As Integer
        Dim iCenter As Integer
        If DrawHover Then
            If Not Me.HoverImage Is Nothing Then
                iWidth = Me.HoverImage.Width
                iHeight = Me.HoverImage.Height
            Else
                If Not Me.Image Is Nothing Then
                    iWidth = Me.Image.Width
                    iHeight = Me.Image.Height
                End If
            End If
        Else
            If Not Me.Image Is Nothing Then
                iWidth = Me.Image.Width
                iHeight = Me.Image.Height
            End If
        End If

        ' Make sure we even need to draw an image to begin

        ' with. There may not be any images in this control.

        If Not iHeight = 0 Then
            ' Ge the position of the image

            Select Case ImageAlign
                Case ContentAlignment.BottomCenter
                    ptImage = 
                       New Point(Convert.ToInt32((Me.Width / 2) - (iWidth / 2)), 
                                                     (Me.Height - iHeight) - 3)
                Case ContentAlignment.BottomLeft
                    ptImage = New Point(5, (Me.Height - iHeight) - 3)
                Case ContentAlignment.BottomRight
                    ptImage = New Point((Me.Width - iWidth) - 5, 
                                           (Me.Height - iHeight) - 3)
                Case ContentAlignment.MiddleCenter
                    ptImage = 
                        New Point(Convert.ToInt32((Me.Width / 2) - (iWidth / 2)), 
                               Convert.ToInt32((Me.Height / 2) - (iHeight / 2)))
                Case ContentAlignment.MiddleLeft
                    ptImage = 
                      New Point(5, Convert.ToInt32((Me.Height / 2) - (iHeight / 2)))
                Case ContentAlignment.MiddleRight
                    ptImage = New Point((Me.Width - iWidth) - 5, 
                                   Convert.ToInt32((Me.Height / 2) - (iHeight / 2)))
                Case ContentAlignment.TopCenter
                    ptImage = 
                        New Point(Convert.ToInt32((Me.Width / 2) - (iWidth / 2)), 5)
                Case ContentAlignment.TopLeft
                    ptImage = New Point(5, 5)
                Case ContentAlignment.TopRight
                    ptImage = New Point((Me.Width - iWidth) - 5, 5)
            End Select

            If DrawHover Then
                If Not Me.HoverImage Is Nothing Then
                    g.DrawImage(Me.HoverImage, ptImage.X, ptImage.Y, 
                          Me.HoverImage.Width, Me.HoverImage.Height)
                Else
                    If Not Me.Image Is Nothing Then
                        g.DrawImage(Me.Image, ptImage.X, ptImage.Y, 
                                    Me.Image.Width, Me.Image.Height)
                    End If
                End If
            Else
                If Not Me.Image Is Nothing Then
                    g.DrawImage(Me.Image, ptImage.X, ptImage.Y, 
                                    Me.Image.Width, Me.Image.Height)
                End If
            End If
        End If

        ' Get the dimensions of the text.

        ' This will return a SizeF object that has height, width, etc.

        Dim ptSize As SizeF = g.MeasureString(Text, Font)

        Dim ptF As New PointF
        ' Get the location to set the Text.

        Select Case Me.TextAlign
            Case ContentAlignment.BottomCenter
                ptF.Y = Me.Height
                ptF.Y -= ptSize.Height
                ptF.X = Convert.ToInt32(Me.Width / 2)
                ptF.X -= ptSize.Width / 2

            Case ContentAlignment.BottomLeft
                ptF.Y = Me.Height
                ptF.Y -= ptSize.Height
                ptF.X = 2

            Case ContentAlignment.BottomRight
                ptF.Y = Me.Height
                ptF.Y -= ptSize.Height
                ptF.X = Me.Width
                ptF.X -= ptSize.Width

            Case ContentAlignment.MiddleCenter
                ptF.Y = Convert.ToInt32(Me.Height / 2)
                ptF.Y -= ptSize.Height / 2
                ptF.X = Convert.ToInt32(Me.Width / 2)
                ptF.X -= ptSize.Width / 2

            Case ContentAlignment.MiddleLeft
                ptF.Y = Convert.ToInt32(Me.Height / 2)
                ptF.Y -= ptSize.Height / 2
                ptF.X = 0

            Case ContentAlignment.MiddleRight
                ptF.Y = Convert.ToInt32(Me.Height / 2)
                ptF.Y -= ptSize.Height / 2
                ptF.X = Me.Width
                ptF.X -= ptSize.Width

            Case ContentAlignment.TopCenter
                ptF.Y = 0
                ptF.X = Convert.ToInt32(Me.Width / 2)
                ptF.X -= ptSize.Width / 2

            Case ContentAlignment.TopLeft
                ptF.Y = 0
                ptF.X = 0

            Case ContentAlignment.TopRight
                ptF.Y = 0
                ptF.X = Me.Width
                ptF.X -= ptSize.Width
        End Select

        If _HasFocus AndAlso Not Me.Selected Then
            ' Draw the Text for the control using the HoverForeColor

            If Not Me.HoverForeColor.Equals(Color.Empty) Then
                g.DrawString(Me.Text, Me.Font, 
                            New SolidBrush(Me.HoverForeColor), ptF)
            Else
                g.DrawString(Me.Text, Me.Font, 
                            New SolidBrush(Me.ForeColor), ptF)
            End If
        Else
            ' Draw the Text for the control

            g.DrawString(Me.Text, Me.Font, 
                            New SolidBrush(Me.ForeColor), ptF)
        End If

        ' Draw the border

        If Border Then
            If Not BorderColor.Equals(Color.Empty) Then
                Dim linePen As New Pen(New SolidBrush(_BorderColor), 1)
                g.DrawRectangle(linePen, New Rectangle(0, 0, Me.Width - 1, 
                                                          Me.Height - 1))
            End If
        End If
    End Sub

Building custom or UserControls are fun and easy once you get the basics down. This control still has lots of room for improvement such as setting the hover or backcolor as gradient, etc.

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