Introduction
This class extends the native .NET progress bar with a percentage property that can be displayed inside the progress bar, and is used to get or set the value of the bar itself. The text can be aligned with the Alignment
property and also has Font
and Padding
properties to allow further customization. On top of this, you can change the color of the percentage that is in the colored part of the progress bar.
Why ANOTHER progress bar control, you might ask yourself. Simple. Before creating this control, I did quite some research into finding a control that enabled displaying a percentage in a progress bar. Most of them succeeded in doing this with varying degrees of customization options, and worked fine in Windows XP. However, once using it on a Vista, the percentage would get deleted because the bar continuously redraws itself. This control will automatically redraw the percentage when the bar is refreshed.
Background
This class contains a lot of code based upon work by people on VB.NET forums. Go to this thread for more information. I am using this component in multiple VB.NET applications without any problems, and it should work in projects in other .NET languages.
Using the Code
Once you added the class to your project, you should be able to add the new component to your forms with the designer or do it manually with code.
Here you have an overview of properties that have been added:
<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 Then m_decimals = value
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
<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)
m_p_align = value
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)
m_overLayFont = value
End Set
End Property
<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)
m_auto_update = value
End Set
End Property
<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
<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
Example
A simple example of setting a few properties:
With Me.ProgressbarWithPercentage1
.ForeColor = Drawing.Color.DimGray
.OverLayColor = Drawing.Color.Black
.PercentageAlign = Drawing.ContentAlignment.MiddleLeft
.Padding = New Windows.Forms.Padding(20, 0, 0, 0)
End With
Inside the Component
Now how does it actually work? I'll try to give you a reasonable understanding.
The most important method is the ShowText
method, which draws a string
onto the progress bar. This method can be used to draw any string
, but is internally only used to draw the percentage.
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)
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)
reg1.Dispose()
reg2.Dispose()
End Sub
This method is used by the ShowPercentage
method in a pretty straight forward way:
Public Sub ShowPercentage()
Me.ShowText(Math.Round(Me.Percentage, _
Me.PercentageDecimals).ToString & "%")
End Sub
The rectangle to draw in is determined every time the control is resized and every time the padding is changed with the following code:
Private Sub setDrawingRectangle()
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
Note that this property is used for every draw event. Another property used for every draw event is the stringformat
. This is set every time you change the alignment.
Private Sub setStringFormat()
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
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
History
Changes in version 1.0.10
- Added percentage format property, allowing you to use custom formats
- Fixed XP bug, that caused the percentage not to be displayed properly
- Created SourceForge project for SVN capabilities
Changes in version 1.0.9
- Fixed a number of dispose issues (a LOT of thanks to JohnH for helping me with this!)
- Fixed bug in percentage calculation when using multiple decimals
- Added an auto increment function to the demo and added decimals to a few bars
Changes in version 1.0.6
- Improved component efficiency by not recalculating some values for every draw event
- Added multiple new events
Changes in version 1.0.5
- Added extra documentation and events
Changes in version 1.0.4
- Fixed alignment bug
- Added padding property