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

Customisable WinForms Progressbar Control VB.NET

0.00/5 (No votes)
2 Apr 2016 1  
A progress bar control you can customize

Introduction

The current winforms progressbar control does not include any customisable options or properties, and the control cannot be inherited so we have to code our own.

The MSDN example I followed was https://support.microsoft.com/en-us/kb/323088.

The above example uses a User Control, but I'd like to use a class control instead, if you decide then of course you can make a user control from within your project.

I wanted a progress bar control I could customize but also still be a progress bar instead of random shapes and styles one wouldn't usually use in an application (well professionally anyway).

Using the Code

This control was made using .NET Framework 4.0.

Ok let's go, start a new Visual Studio project and choose, Class Library, and name it appropriately.

Now in the solution explorer, right mouse click on the project name and select add reference, then from the .NET tab, add the following:

  • System
  • System.Drawing
  • System.Windows.Forms

Now let's Import and start coding. Add the following:

Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

Public Class Progress_bar : Inherits Control

'#Region "Variables"    ' UnComment the '#Region lines to make the code collapsible

    Private min As Integer = 0
    Private max As Integer = 100
    Private val As Integer = 0
    Public usegrad As Boolean = False
    Public bkColor As Color = Color.Transparent
    Public enBackColor As Boolean = False
    Public BarColor As Color = Color.Blue
    Public gradcolor1 As Color = Color.DeepSkyBlue
    Public gradcolor2 As Color = Color.Blue
    Dim HColor As Color = Color.WhiteSmoke
    Dim hStyle As HatchStyle
    Dim drawhBrush As Boolean = False
    Dim hatchBackColor As Color = Color.Transparent '?
    Public drwLabel As Boolean = False
    Public draw3D As Boolean = False

'#End Region

'#Region "New/Create Control"

    Public Sub New()
        MyBase.New()
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
    End Sub

    Protected Overrides Sub OnCreateControl()
        MyBase.OnCreateControl()
    End Sub

'#End Region

'#Region"Properties"

    Public Property Minimum() As Integer
        Get
            Return min
        End Get
        Set(ByVal Value As Integer)
            '
            If (Value < 0) Then
                min = 0
            End If
            '
            If (Value > max) Then
                min = Value
                min = Value
            End If
            '
            If (Value < min) Then
                val = min
            End If
            '
            Me.Invalidate()
            '
        End Set
    End Property

    Public Property Maximum() As Integer
        Get
            Return max
        End Get
        Set(ByVal Value As Integer)

            If (Value < min) Then
                min = Value
            End If

            max = Value

            If (val > max) Then
                val = max
            End If

            Me.Invalidate()

        End Set
    End Property

    Public Property Value As Integer
        '
        Get
            Return val
        End Get
        '
        Set(ByVal Value As Integer)
            Dim oldvalue As Integer = val
            '
            If (Value < min) Then
                val = min
            ElseIf (Value > max) Then
                val = max
            Else
                val = Value
            End If
            '
            Dim newValueRect As Rectangle = Me.ClientRectangle
            Dim oldValueRect As Rectangle = Me.ClientRectangle
            Dim percent As Decimal
            '
            percent = (val - min) / (max - min)
            newValueRect.Width = newValueRect.Width * percent
            '
            percent = (oldvalue - min) / (max - min)
            oldValueRect.Width = oldValueRect.Width * percent
            '
            Dim updateRect As Rectangle = New Rectangle()
            '
            If (newValueRect.Width > oldValueRect.Width) Then
                updateRect.X = oldValueRect.Size.Width
                updateRect.Width = newValueRect.Width - oldValueRect.Width
            Else
                updateRect.X = newValueRect.Size.Width
                updateRect.Width = oldValueRect.Width - newValueRect.Width
            End If
            '
            updateRect.Height = Me.Height
            '
            Me.Invalidate(updateRect.X)
        End Set
        '
    End Property

    Public Property ProgressBarColor() As Color
        Get
            Return BarColor
        End Get
        Set(ByVal Value As Color)
            BarColor = Value
            Me.Invalidate()
        End Set
    End Property

    Public Property GradientColor1() As Color
        Get
            Return gradcolor1
        End Get
        Set(ByVal value As Color)
            gradcolor1 = value
            Me.Invalidate()
        End Set
    End Property

    Public Property GradientColor2() As Color
        Get
            Return gradcolor2
        End Get
        Set(ByVal value As Color)
            gradcolor2 = value
            Me.Invalidate()
        End Set
    End Property

    Public Property UseHatchBrush() As Boolean
        Get
            Return drawhBrush
        End Get
        Set(ByVal value As Boolean)
            drawhBrush = value
            Me.Invalidate()
        End Set
    End Property

    Public Property HatchColor() As Color
        Get
            Return HColor
        End Get
        Set(ByVal value As Color)

            HColor = value
            Me.Invalidate()
        End Set
    End Property

    Public Property HatchStyle() As HatchStyle
        Get
            Return hStyle
        End Get
        Set(ByVal value As HatchStyle)
            hStyle = value
            Me.Invalidate()
        End Set
    End Property

    Public Property UseGradient() As Boolean
        Get
            Return usegrad
        End Get
        Set(ByVal value As Boolean)
            usegrad = value
            Me.Invalidate()
        End Set
    End Property

    Public Property DrawLabel() As Boolean
        Get
            Return drwLabel
        End Get
        Set(ByVal value As Boolean)
            drwLabel = value
            Me.Invalidate()
        End Set
    End Property

    Public Property Draw3DBorder() As Boolean
        Get
            Return draw3D
        End Get
        Set(ByVal value As Boolean)
            draw3D = value
            Me.Invalidate()
        End Set
    End Property

    Public Shadows Property BackColor() As Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal value As Color)
            MyBase.BackColor = value
            Me.Invalidate()
        End Set
    End Property

'#End Region

    Private Sub Draw_3D_Border(ByVal g As Graphics)
        '
        Dim penWidth As Integer = Pens.White.Width
        g.DrawLine(Pens.DarkGray, New Point(Me.ClientRectangle.Left, _
        Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Width - _
        penWidth, Me.ClientRectangle.Top))
        g.DrawLine(Pens.DarkGray, New Point(Me.ClientRectangle.Left, _
        Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Left, _
        Me.ClientRectangle.Height - penWidth))
        g.DrawLine(Pens.White, New Point(Me.ClientRectangle.Left, _
        Me.ClientRectangle.Height - penWidth), New Point(Me.ClientRectangle.Width - _
        penWidth, Me.ClientRectangle.Height - penWidth))
        g.DrawLine(Pens.White, New Point(Me.ClientRectangle.Width -_ 
        penWidth, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Width - _
        penWidth, Me.ClientRectangle.Height - penWidth))
        '
    End Sub

    Protected Overrides Sub OnResize(ByVal e As EventArgs)
        Me.Invalidate()     'Invalidate to resize control
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        '
        Dim g As Graphics = e.Graphics
        Dim brush As SolidBrush = New SolidBrush(BarColor) ' new solid brush from BarColor
        Dim bkbrush As New SolidBrush(MyBase.BackColor)    ' new solidbrush from backcolor
        Dim hbrush As New HatchBrush(hStyle, _
        HColor, Color.Transparent) ' new hatch brush (forecolor, backcolor)
        'new lineargradient brush
        Dim gbrush As LinearGradientBrush = New LinearGradientBrush_
        (Me.ClientRectangle, Color.FromArgb(255, gradcolor1), _
        Color.FromArgb(255, gradcolor2), LinearGradientMode.Vertical)
        Dim percent As Decimal = (val - min) / (max - min) ' calculate the percent
        Dim cliRect As Rectangle = New Rectangle(0, 0, _
        Me.ClientRectangle.Width, Me.ClientRectangle.Height) ' Control rectangle
        Dim rect As Rectangle = New Rectangle(1, 1, _
        Me.ClientRectangle.Width - 2, Me.ClientRectangle.Height - 2) ' Progress rectangle
        '
        rect.Width = rect.Width * percent
        '
        ' Smoothing and quality mode
        g.SmoothingMode = SmoothingMode.AntiAlias
        g.CompositingQuality = CompositingQuality.AssumeLinear
        '
        If UseGradient = True Then
            g.FillRectangle(bkbrush, cliRect) ' enable back color
            g.FillRectangle(gbrush, rect)     ' Use Gradient
            If drawhBrush = True Then
                g.FillRectangle(hbrush, rect) ' draw hatch brush
            End If

        End If
        '
        If UseGradient = False Then
            g.FillRectangle(bkbrush, cliRect)
            g.FillRectangle(brush, rect)
            If drawhBrush = True Then
                g.FillRectangle(hbrush, rect)
            End If
            ' g.DrawRectangle(Pens.Black, cliRect)  ' Draw a single Border
        End If
        '
        If draw3D = True Then
            Draw_3D_Border(g) ' draw the 3d border using g as graphics
        End If
        '
        If DrawLabel = True Then
            Dim str As String = CType(val & "%", String) ' convert val into a string
            Dim mybrush As New SolidBrush(Me.ForeColor)  ' make ForeColor as brush
            g.DrawString(str, Me.Font, mybrush, _
            New Point((Me.ClientRectangle.Width / 2) - str.Length * 4, _
            (Me.ClientRectangle.Height / 2) - (FontHeight / 2))) ' Draw string 
        End If
        '
        brush.Dispose()
        bkbrush.Dispose()
        hbrush.Dispose()
        gbrush.Dispose()
        g.Dispose()
        '
    End Sub

End Class

Some of the styles that can be achieved are as shown below:

ToDo

  • Round corners (the code I had didn't work properly)
  • Selectable region
  • Animated Hatch Brush

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