'**************************************************************'
' BN+ Framework: Stand alone component '
' By De Dauw Jeroen -
jeroendedauw@gmail.com '
'**************************************************************'
' Namespace Bn.Components '
' Component ProgressbarWithPercentage v1.0.6 - March 2009 '
'**************************************************************'
' Copyright 2009 - BN+ Discussions '
' http://code.bn2vs.com '
'**************************************************************'
' Author notes
' > Although this class is part of BN+ Framwework, it can be used as a stand alone without modifications
' > The maximum amount of decimals that can be displayed is determined by the difference between minimum and maximum value.
' Mathematical: max decimals = x - 2 with x sqrt(max value - min value) = 10
' Example: If min value = 0 and you want 2 decimals, max value should be at least 10000
Option Strict On : Option Explicit On
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
Namespace Bn.Components
#Region " Public Class ProgressbarWithPercentage "
''' <summary>Component that extends the native .net progressbar with percentage properties and the ability to display it in the progressbar</summary>
''' <remarks>Component ProgressbarWithPercentage v1.0.6, by De Dauw Jeroen - March 2009</remarks>
<DesignTimeVisible(True)> _
Public Class ProgressbarWithPercentage
Inherits System.Windows.Forms.ProgressBar
#Region "Events"
''' <summary>Occurs when the value of the progress bar is changed</summary>
<Category("Property Changed")> _
Public Event ValueChanged As EventHandler
''' <summary>Occurs when the amount of decimals to be displayed in the percentage is changed</summary>
<Category("Property Changed")> _
Public Event PercentageDecimalsChanged As EventHandler
''' <summary>Occurs when the visibility of the percentage text is changed</summary>
<Category("Property Changed")> _
Public Event PercentageVisibleChanged As EventHandler
''' <summary>Occurs when the automatic updating of the percentage is turned on or off</summary>
<Category("Property Changed")> _
Public Event AutoUpdatePercentageChanged As EventHandler
''' <summary>Occurs when the OverLayColor property is changed</summary>
<Category("Property Changed")> _
Public Event OverLayColorChanged As EventHandler
''' <summary>Occurs when the align of the percentage text is changed</summary>
<Category("Property Changed")> _
Public Event PercentageAlignChanged As EventHandler
''' <summary>Occurs when the padding of the percentage text is changed</summary>
<Category("Property Changed")> _
Public Shadows Event PaddingChanged As EventHandler
#End Region
#Region "Fields"
Private Const WM_PAINT As Int32 = &HF
Private m_auto_update, m_p_visible As Boolean
Private m_decimals As Int32
Private m_p_align As ContentAlignment
Private m_graphics As Graphics
Private m_overLayFont As Color
Private m_drawingRectangle As RectangleF
Private m_strFormat As New StringFormat
#End Region
#Region "Public methods"
''' <summary>Create a new instance of a ProgressbarWithPercentage</summary>
Public Sub New()
' Initialize the base class
MyBase.New()
' Set the default values of the properties
Me.Graphics = Me.CreateGraphics
Me.AutoUpdatePercentage = True
Me.PercentageVisible = True
Me.PercentageDecimals = 0
Me.PercentageAlign = ContentAlignment.MiddleCenter
Me.OverLayColor = Color.Black
Me.ForeColor = Color.DimGray
End Sub
''' <summary>Advances the current possition of the progressbar by the amount of the Step property</summary>
Public Shadows Sub PerformStep()
MyBase.PerformStep()
If Me.PercentageVisible And Me.AutoUpdatePercentage Then Me.ShowPercentage()
End Sub
''' <summary>Show the current percentage as text</summary>
Public Sub ShowPercentage()
Me.ShowText(Math.Round(Me.Percentage, Me.PercentageDecimals).ToString & "%")
End Sub
''' <summary>Display a string on the progressbar</summary>
''' <param name="text">Required. String. The string to display</param>
Public Sub ShowText(ByVal text As String)
Dim r1 As RectangleF = Me.ClientRectangle
r1.Width = CSng(r1.Width * Me.Value / Me.Maximum)
Dim reg1 As New Region(r1)
Dim reg2 As New Region(Me.ClientRectangle)
reg2.Exclude(reg1)
' Draw the percentage
Me.Graphics.Clip = reg1
Me.Graphics.DrawString(text, Me.Font, New SolidBrush(Me.OverLayColor), Me.DrawingRectangle, m_strFormat)
Me.Graphics.Clip = reg2
Me.Graphics.DrawString(text, Me.Font, New SolidBrush(Me.ForeColor), Me.DrawingRectangle, m_strFormat)
End Sub
#End Region
#Region "Protected methods"
Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs)
MyBase.OnHandleCreated(e)
Graphics = Graphics.FromHwnd(Me.Handle)
End Sub
Protected Overrides Sub OnHandleDestroyed(ByVal e As System.EventArgs)
Graphics.Dispose()
MyBase.OnHandleDestroyed(e)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_PAINT And Me.PercentageVisible And Me.AutoUpdatePercentage Then ShowPercentage()
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Me.AutoUpdatePercentage = False
MyBase.Dispose(disposing)
End Sub
#End Region
#Region "Private methods"
Private Sub ProgressbarWithPercentage_SizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.SizeChanged
setDrawingRectangle()
' Set the graphics
Me.Graphics = Me.CreateGraphics
End Sub
Private Sub ProgressbarWithPercentage_PaddingChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.PaddingChanged
setDrawingRectangle()
End Sub
Private Sub setDrawingRectangle()
' Determine the coordinates and size of the drawing rectangle depending on the progress bar size and padding
Me.DrawingRectangle = New RectangleF(Me.Padding.Left, _
Me.Padding.Top, _
Me.Width - Me.Padding.Left - Me.Padding.Right, _
Me.Height - Me.Padding.Top - Me.Padding.Bottom)
End Sub
Private Sub setStringFormat()
' Determine the horizontal alignment
Select Case Me.PercentageAlign
Case ContentAlignment.BottomCenter, ContentAlignment.BottomLeft, ContentAlignment.BottomRight
m_strFormat.LineAlignment = StringAlignment.Far
Case ContentAlignment.MiddleCenter, ContentAlignment.MiddleLeft, ContentAlignment.MiddleRight
m_strFormat.LineAlignment = StringAlignment.Center
Case ContentAlignment.TopCenter, ContentAlignment.TopLeft, ContentAlignment.TopRight
m_strFormat.LineAlignment = StringAlignment.Near
End Select
' Determine the vertical alignment
Select Case Me.PercentageAlign
Case ContentAlignment.BottomLeft, ContentAlignment.MiddleLeft, ContentAlignment.TopLeft
m_strFormat.Alignment = StringAlignment.Near
Case ContentAlignment.BottomCenter, ContentAlignment.MiddleCenter, ContentAlignment.TopCenter
m_strFormat.Alignment = StringAlignment.Center
Case ContentAlignment.BottomRight, ContentAlignment.MiddleRight, ContentAlignment.TopRight
m_strFormat.Alignment = StringAlignment.Far
End Select
End Sub
#End Region
#Region "Properties"
#Region "Appearance"
<Browsable(True), Category("Appearance"), Description("The value of the progressbar")> _
Public Shadows Property Value() As Int32
Get
Return MyBase.Value
End Get
Set(ByVal value As Int32)
If value <> Me.Value Then
MyBase.Value = value
If Me.PercentageVisible And Me.AutoUpdatePercentage Then Me.ShowPercentage()
RaiseEvent ValueChanged(Me, New EventArgs)
End If
End Set
End Property
<Browsable(True), Category("Appearance"), Description("The percentage of the progressbar")> _
Public Property Percentage() As Double
Get
Return Me.Value / Me.Maximum * 100
End Get
Set(ByVal value As Double)
If value >= 0 And value <= 100 Then
Me.Value = CInt(Me.Maximum * value / 100)
If Me.PercentageVisible And Me.AutoUpdatePercentage Then Me.ShowPercentage()
End If
End Set
End Property
<Browsable(True), Category("Appearance"), DefaultValue(0), Description("Gets or sets the amount of decimals that will be displayed in the percentage")> _
Public Overridable Property PercentageDecimals() As Int32
Get
Return m_decimals
End Get
Set(ByVal value As Int32)
If value > -1 And value <> Me.PercentageDecimals Then
m_decimals = value
RaiseEvent PercentageDecimalsChanged(Me, New EventArgs)
End If
End Set
End Property
<Browsable(True), Category("Appearance"), Description("Gets or sets the font of the percentage text")> _
Public Overridable Overloads Property Font() As Font
Get
Return MyBase.Font
End Get
Set(ByVal value As Font)
MyBase.Font = value
End Set
End Property
<Browsable(True), Category("Appearance"), DefaultValue("MiddleCenter"), Description("Gets or sets if the percentage alignment")> _
Public Overridable Property PercentageAlign() As ContentAlignment
Get
Return m_p_align
End Get
Set(ByVal value As ContentAlignment)
If value <> Me.PercentageAlign Then
m_p_align = value
setStringFormat()
RaiseEvent PercentageAlignChanged(Me, New EventArgs)
End If
End Set
End Property
<Browsable(True), Category("Appearance"), Description("Gets or sets the color of the percentage text at the place of the progressbar that is indicated")> _
Public Overridable Property OverLayColor() As Color
Get
Return m_overLayFont
End Get
Set(ByVal value As Color)
If Me.m_overLayFont <> value Then
m_overLayFont = value
RaiseEvent OverLayColorChanged(Me, New EventArgs)
End If
End Set
End Property
<Browsable(True), Category("Appearance"), DefaultValue(True), Description("Gets or sets if the percentage should be visible")> _
Public Overridable Property PercentageVisible() As Boolean
Get
Return m_p_visible
End Get
Set(ByVal value As Boolean)
If value <> Me.PercentageVisible Then
If Not value Then Me.Graphics.Clear(Color.Transparent)
m_p_visible = value
RaiseEvent PercentageVisibleChanged(Me, New EventArgs)
End If
End Set
End Property
#End Region
#Region "Behavior"
<Browsable(True), Category("Behavior"), DefaultValue(True), Description("Gets or sets if the percentage should be auto updated")> _
Public Overridable Property AutoUpdatePercentage() As Boolean
Get
Return m_auto_update
End Get
Set(ByVal value As Boolean)
If value <> Me.AutoUpdatePercentage Then
m_auto_update = value
RaiseEvent AutoUpdatePercentageChanged(Me, New EventArgs)
End If
End Set
End Property
#End Region
#Region "Layout"
<Browsable(True), Category("Layout"), Description("Gets or sets if the interior spacing of the control")> _
Public Overridable Overloads Property Padding() As Padding
Get
Return MyBase.Padding
End Get
Set(ByVal value As Padding)
MyBase.Padding = value
End Set
End Property
#End Region
#Region "Misc"
Protected Overridable Property Graphics() As Graphics
Get
Return m_graphics
End Get
Set(ByVal value As Graphics)
m_graphics = value
End Set
End Property
Private Property DrawingRectangle() As RectangleF
Get
Return m_drawingRectangle
End Get
Set(ByVal value As RectangleF)
m_drawingRectangle = value
End Set
End Property
#End Region
#End Region
#Region "Designer"
Private Sub InitializeComponent()
Me.SuspendLayout()
'
'ProgressbarWithPercentage
'
Me.ResumeLayout(False)
End Sub
#End Region
End Class
#End Region
End Namespace