Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Writing text to progress bar OnPaint not working.

Status
Not open for further replies.

Sorwen

Technical User
Nov 30, 2002
1,641
US
I've used the OnPaint even to write graphics to the screen before and it has always worked. This is the only the second time I've done text however and it doesn't want to work this time. In the past I was only drawing to the form though and not a control. I've tried a few different ways, but here is currently how the code looks.

Code:
Public Class ProgressBarWithText
    Inherits System.Windows.Forms.ProgressBar

    Private MyBrush As New System.Drawing.SolidBrush(Drawing.Color.Black)

#Region "Properties"
    Public Shadows Property Value() As Integer
        Get
            Return MyBase.Value
        End Get
        Set(ByVal value As Integer)
            MyBase.Value = value

            RaiseEvent ValueChanged(Me)
        End Set
    End Property
#End Region

#Region "Events"
    Public Event ValueChanged(ByVal sender As Object)
#End Region

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If Me.Visible = True Then
            Dim x As Single
            Dim y As Single
            Dim text As String = Me.Value & "/" & Me.Maximum
            Dim sizeF As System.Drawing.SizeF = Me.CreateGraphics.MeasureString(text, Me.Font, Me.Width)

            x = (Me.Width / 2) - (sizeF.Width / 2)
            y = (Me.Height / 2) - (sizeF.Height / 2)
            e.Graphics.DrawString(text, Me.Font, Me.MyBrush, x, y)
        End If

        MyBase.OnPaint(e)
    End Sub

End Class
Is it something about the OnPaint event itself that is causing it? I have found another way to do this, but I would prefer the control to write this to itself rather than always needing to remember to write it else where. Also, I wanted the OnPaint event so if something else caused it to repaint before the value updated it would still show the progress values and not wait until the value was updated.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
It doesn't work for me either. If you don't mind a bit of background showing, the following will work
Code:
Public Class ProgressBarWithText2
    Inherits System.Windows.Forms.ProgressBar
    Private WithEvents mLabel As Label

    Public Shadows Property Value() As Integer
        Get
            Return MyBase.Value
        End Get
        Set(ByVal value As Integer)
            MyBase.Value = value
            Try
                Me.mLabel.Text = Me.Value.ToString & "/" & Me.Maximum.ToString
            Catch ex As Exception

            End Try
        End Set
    End Property

    Private Sub ProgressBarWithText2_ParentChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ParentChanged
        If Me.Controls.Count = 0 Then
            Me.mLabel = New Label
            Me.mLabel.AutoSize = True
            Me.Controls.Add(Me.mLabel)
            Me.mLabel.Left = (Me.Width / 2) - (Me.mLabel.Width / 2)
            Me.mLabel.Top = (Me.Height / 2) - (Me.mLabel.Height / 2)
        End If
    End Sub
End Class
 
Thanks for the help RiverGuy. Knowing that I wasn't the only one made me think and revise my google search. Instead of "vb.net progress bar with text" I looked up "vb.net progress bar onpaint" and got a lot of answers. These two explained fine though.


And in the comments at the bottom.
I'm not sure what the DoubleBuffer does, but it wasn't needed so I left it out. Code is now:
Code:
Public Class ProgressBarWithText
    Inherits System.Windows.Forms.ProgressBar

    Private WithEvents mlabel As System.Windows.Forms.Label
    Private MyBrush As New System.Drawing.SolidBrush(Drawing.Color.Black)

    Sub New()
        MyBase.New()
        Me.SetStyle(Windows.Forms.ControlStyles.UserPaint, True)
    End Sub

#Region "Properties"
    Public Shadows Property Value() As Integer
        Get
            Return MyBase.Value
        End Get
        Set(ByVal value As Integer)
            MyBase.Value = value

            RaiseEvent ValueChanged(Me)
        End Set
    End Property
#End Region

#Region "Events"
    Public Event ValueChanged(ByVal sender As Object)
#End Region

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim x As Single
        Dim y As Single
        Dim text As String = Me.Value & "/" & Me.Maximum
        Dim sizeF As System.Drawing.SizeF = Me.CreateGraphics.MeasureString(text, Me.Font, Me.Width)

        x = (Me.Width / 2) - (sizeF.Width / 2)
        y = (Me.Height / 2) - (sizeF.Height / 2)
        e.Graphics.DrawString(text, Me.Font, Me.MyBrush, x, y)

        MyBase.OnPaint(e)
    End Sub
End Class

It works fine now. :) I need to read more to see if there was a reason given why it is needed.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Correction. It kind of works. The text is there now, but the progress no longer shows.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
When in doubt build it yourself. Ok so I couldn't find any way for it to work on its own so I had to create the bar myself. I figured if I was going to do that I should add more functionality to it. I'm going to add this to the FAQ section as well once I have it more documented. Note this only works for 2k8. I learned today while finding information that 2k5 cannot inherit from the ProgressBar control. There are step-by-step for creating a smooth ProgressBar from a control is here:
Now for my code:
Code:
Public Class CustomProgressBar
    Inherits System.Windows.Forms.ProgressBar

    Enum BarTextStyle
        DefaultText = 0
        ValueText = 1
        ValueOfMax = 2
        PercentText = 3
    End Enum

    Enum BrushBarStyle
        Block = 0
        GradientHorizontal = 1
        GradientVertical = 2
        Solid = 3
        Picture = 4
    End Enum

    Private MyFont As System.Drawing.Font = Me.Font
    Private MyBrush As New System.Drawing.SolidBrush(Drawing.Color.Black)
    Private _BarStyle As BrushBarStyle
    Private _BackColor As System.Drawing.Color
    Private _Picture As System.Drawing.Image
    Private _TextStyle As BarTextStyle


    Sub New()
        MyBase.New()
        Me.SetStyle(Windows.Forms.ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(Windows.Forms.ControlStyles.UserPaint, True)
        Me.SetStyle(Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(Windows.Forms.ControlStyles.ResizeRedraw, True)

        Me.BarStyle = BrushBarStyle.Solid
        Me.BackColor = System.Drawing.SystemColors.Control
        Me.ForeColor = System.Drawing.SystemColors.Highlight
    End Sub


#Region "Properties"
    Public Shadows Property Value() As Integer
        Get
            Return MyBase.Value
        End Get
        Set(ByVal value As Integer)
            If value < Me.Minimum Then
                value = Me.Minimum
            ElseIf value > Me.Maximum Then
                value = Me.Maximum
            End If

            MyBase.Value = value
            RaiseEvent ValueChanged(Me)
            Me.Invalidate()
        End Set
    End Property

    <ComponentModel.DefaultValue(BrushBarStyle.Solid)> _
    Public Property BarStyle() As BrushBarStyle
        Get
            Return _BarStyle
        End Get
        Set(ByVal value As BrushBarStyle)
            _BarStyle = value
        End Set
    End Property

    <ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "Highlight")> _
    Public Overrides Property ForeColor() As System.Drawing.Color
        Get
            Return MyBase.ForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            MyBase.ForeColor = value
        End Set
    End Property

    <ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "Control")> _
    Public Overrides Property BackColor() As System.Drawing.Color
        Get
            Return _BackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            _BackColor = value
        End Set
    End Property

    <ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "Control")> _
    Public Property ControlColor() As System.Drawing.Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            MyBase.BackColor = value
        End Set
    End Property

    Public Property Picture() As System.Drawing.Image
        Get
            Return _Picture
        End Get
        Set(ByVal value As System.Drawing.Image)
            _Picture = value
        End Set
    End Property

    <ComponentModel.DefaultValue(BarTextStyle.DefaultText)> _
    Public Property TextStyle() As BarTextStyle
        Get
            Return _TextStyle
        End Get
        Set(ByVal value As BarTextStyle)
            _TextStyle = value
        End Set
    End Property
#End Region

#Region "Events"
    Public Event ValueChanged(ByVal sender As Object)
#End Region

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If Me IsNot Nothing Then
            PaintBar(e.Graphics)
            PaintText(e.Graphics)
        End If

        MyBase.OnPaint(e)
    End Sub

    'Paint a bar graphic to the control
    Private Sub PaintBar(ByVal sender As System.Drawing.Graphics)
        'If text is painted then a bar must be painted as it will no longer show on its own.
        Dim percentage As Integer = (Me.Value / Me.Maximum * Me.ClientRectangle.Width)
        Dim rect As New System.Drawing.RectangleF(Me.ClientRectangle.X, Me.ClientRectangle.Y, percentage, Me.ClientRectangle.Height)
        Dim BarBrush As System.Drawing.Brush

        Select Case _BarStyle
            Case BrushBarStyle.Block
                BarBrush = New System.Drawing.Drawing2D.HatchBrush(Drawing.Drawing2D.HatchStyle.Vertical, Me.BackColor, Me.ForeColor)
            Case BrushBarStyle.GradientHorizontal
                If percentage > 0 Then BarBrush = New System.Drawing.Drawing2D.LinearGradientBrush(rect, Me.ForeColor, Me.BackColor, Drawing.Drawing2D.LinearGradientMode.Horizontal)
            Case BrushBarStyle.GradientVertical
                If percentage > 0 Then BarBrush = New System.Drawing.Drawing2D.LinearGradientBrush(rect, Me.ForeColor, Me.BackColor, Drawing.Drawing2D.LinearGradientMode.Vertical)
            Case BrushBarStyle.Solid
                BarBrush = New System.Drawing.SolidBrush(Me.ForeColor)
            Case BrushBarStyle.Picture
                If _Picture IsNot Nothing Then BarBrush = New System.Drawing.TextureBrush(_Picture, Drawing.Drawing2D.WrapMode.Tile)
        End Select

        If BarBrush Is Nothing Then BarBrush = New System.Drawing.SolidBrush(Me.ForeColor)

        sender.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighSpeed
        sender.FillRectangle(BarBrush, rect)
        BarBrush.Dispose()
    End Sub

    'Paint text to the control
    Private Sub PaintText(ByVal sender As System.Drawing.Graphics)
        Dim x As Single
        Dim y As Single
        Dim text As String = " "
        Dim sizeF As System.Drawing.SizeF

        Select Case Me.TextStyle
            Case BarTextStyle.DefaultText
                text = Me.Text
            Case BarTextStyle.ValueText
                text = Me.Value
            Case BarTextStyle.ValueOfMax
                text = Me.Value & "/" & Me.Maximum
            Case BarTextStyle.PercentText
                text = (Me.Value / Me.Maximum * 100)
        End Select

        sizeF = Me.CreateGraphics.MeasureString(text, Me.MyFont, Me.Width)
        x = (Me.Width / 2) - (sizeF.Width / 2)
        y = (Me.Height / 2) - (sizeF.Height / 2)

        sender.DrawString(text, Me.MyFont, Me.MyBrush, x, y)
    End Sub

End Class

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Thanks for posting this. I'll have to check it out. I've made a few of these in the past, as well as my own version of the "progress circle" that Microsoft is using on a lot of their software of late. I'll try to find that code and post a FAQ as well.
 
I noticed an error when documenting.

this:
Code:
Case BrushBarStyle.Block
                BarBrush = New System.Drawing.Drawing2D.HatchBrush(Drawing.Drawing2D.HatchStyle.Vertical, Me.BackColor, Me.ForeColor)

should be this:
Code:
Case BrushBarStyle.Block
                BarBrush = New System.Drawing.Drawing2D.HatchBrush(Drawing.Drawing2D.HatchStyle.Vertical, Me.[red]ControlColor[/red], Me.ForeColor)

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
That would be cool RiverGuy. I saw mention of one, but I don't have time right now to create something like that. It would be neat to use however. :)

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
I just noticed that when I stole ForeColor I took away the ability to change the text color. So for those that don't know here is how to add that back and more.

declare:
Code:
Private _Font As System.Drawing.Font
Private _FontColor As System.Drawing.Color
And remove MyFont and MyBrush.

then add to the properties section:
Code:
    <System.ComponentModel.Browsable(True)> _
    Public Overrides Property Font() As System.Drawing.Font
        Get
            Return _Font
        End Get
        Set(ByVal value As System.Drawing.Font)
            _Font = value
        End Set
    End Property

    <ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "WindowText")> _
    Public Property FontColor() As System.Drawing.Color
        Get
            Return _FontColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            _FontColor = value
        End Set
    End Property

Then replace the PaintText with this one:
Code:
    Private Sub PaintText(ByVal sender As System.Drawing.Graphics)
        Dim x As Single
        Dim y As Single
        Dim text As String = " "
        Dim sizeF As System.Drawing.SizeF

        Select Case Me.TextStyle
            Case BarTextStyle.DefaultText
                text = Me.Text
            Case BarTextStyle.ValueText
                text = Me.Value
            Case BarTextStyle.ValueOfMax
                text = Me.Value & "/" & Me.Maximum
            Case BarTextStyle.PercentText
                text = (Me.Value / Me.Maximum * 100)
        End Select

        sizeF = Me.CreateGraphics.MeasureString(text, Me.Font, Me.Width)
        x = (Me.Width / 2) - (sizeF.Width / 2)
        y = (Me.Height / 2) - (sizeF.Height / 2)

        sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(Me.FontColor), x, y)
    End Sub

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
With documentation can be found here: faq796-7154

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
New problem. I'm trying to implement Font highlighting so you can see the text if a dark bar color is used. I've tried a lot of different ways, but none work consistently right. Below is what I'm currently using and it works 100% correctly for the first digit, but after that it is like it falls behind in coloring even though the rectangle reports back the correct size.

Code:
    'Paint text to the control
    Private Sub PaintText(ByVal sender As System.Drawing.Graphics)
        Dim x As Decimal 'Double 'Integer 'Single
        Dim y As Decimal 'Double 'Integer 'Single
        Dim text As String = " "
        Dim sizeF As System.Drawing.SizeF

        Select Case Me.TextStyle
            Case BarTextStyle.DefaultText
                text = Me.Text
            Case BarTextStyle.ValueText
                text = Me.Value
            Case BarTextStyle.ValueOfMax
                text = Me.Value & "/" & Me.Maximum & " " & Me.Font.Size & "/" & Me.Font.Size
            Case BarTextStyle.PercentText
                text = (Me.Value / Me.Maximum * 100)
        End Select

        sizeF = Me.CreateGraphics.MeasureString(text, Me.Font, Me.Width)
        'If Me.FontAutoSize = True Then
        '    If sizeF.ToSize.Height < Me.ClientRectangle.Height - 5 Then sizeF = FontAdjust(sizeF)
        'End If

        x = (Me.ClientRectangle.Width / 2) - (sizeF.ToSize.Width / 2)
        y = (Me.ClientRectangle.Height / 2) - (sizeF.ToSize.Height / 2)

        'Dim TextFormat As New System.Drawing.StringFormat
        'TextFormat.Alignment = Drawing.StringAlignment.Center
        'TextFormat.LineAlignment = Drawing.StringAlignment.Center

        Dim percentage As Double = (Me.Value / Me.Maximum * Me.ClientRectangle.Width)

        ''Dim TempColor As System.Drawing.Color
        ''If percentage > (x + sizeF.ToSize.Width) Then
        ''    TempColor = System.Drawing.SystemColors.HighlightText
        ''Else
        ''    TempColor = Me.FontColor
        ''End If
        'sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(Me.FontColor), x, y)
        sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(Me.FontColor), New System.Drawing.RectangleF(x, y, sizeF.Width, sizeF.Height))


        'If percentage > x And percentage < (x + sizeF.ToSize.Width) Then
        'Dim InText As Integer = Math.Ceiling((percentage - x) / text.Length)
        'Dim Text1 As String = text.Substring(0, InText)
        sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(System.Drawing.SystemColors.HighlightText), New System.Drawing.RectangleF(x, y, (percentage - x), sizeF.Height))

        'sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(System.Drawing.SystemColors.HighlightText), New System.Drawing.RectangleF(Me.ClientRectangle.X, Me.ClientRectangle.Y, (percentage - x), Me.ClientRectangle.Height))
        'End If
    End Sub
Any suggestions?

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Did you get this working yet? I just tried to add this code to a new class, and received and error when adding the control to my form.
 
Everything works just this last part doesn't color right. The above should replace the PaintText sub from the code in the faq (which is the most up-to-date).

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
I should have asked also what kind of error did you get?

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Object reference not set to an instance of an object. Can you post the entire code for the class in one block?
 
The faq FAQ796-7154 has all but the last post. It is a cleaner. Here it is how it sits in my class right now. It has a lot of try this/that junk in it. For instance I've been playing around with some type of auto size for the font, but I'm not sure how I want to work it yet.

Code:
Public Class CustomProgressBar
    Inherits System.Windows.Forms.ProgressBar

    Enum BarTextStyle
        DefaultText = 0
        ValueText = 1
        ValueOfMax = 2
        PercentText = 3
    End Enum

    Enum BrushBarStyle
        Block = 0
        GradientHorizontal = 1
        GradientVertical = 2
        Solid = 3
        Picture = 4
    End Enum

    Private StartFontSize As Single
    Private _BarStyle As BrushBarStyle
    Private _BackColor As System.Drawing.Color
    Private _Picture As System.Drawing.Image
    Private _TextStyle As BarTextStyle
    Private _Font As System.Drawing.Font
    Private _FontColor As System.Drawing.Color
    Private _AllowFontHighlight As Boolean
    Private _FontAutoAdjust As Boolean


    Sub New()
        MyBase.New()
        Me.SetStyle(Windows.Forms.ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(Windows.Forms.ControlStyles.UserPaint, True)
        Me.SetStyle(Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(Windows.Forms.ControlStyles.ResizeRedraw, True)

        Me.BarStyle = BrushBarStyle.Solid
        Me.ControlColor = System.Drawing.SystemColors.Control
        Me.BackColor = System.Drawing.SystemColors.Control
        Me.ForeColor = System.Drawing.SystemColors.Highlight
        Me.Font = MyBase.Font
        Me.FontColor = System.Drawing.SystemColors.WindowText
        Me.TextStyle = BarTextStyle.DefaultText
        Me.StartFontSize = Me.Font.Size
        Me.AllowFontHighlight = True
        Me.FontAutoSize = True
    End Sub


#Region "Properties"
    ''' <summary>
    ''' Gets or sets the current progress.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the current progress.")> _
    Public Shadows Property Value() As Integer
        Get
            Return MyBase.Value
        End Get
        Set(ByVal value As Integer)
            If value < Me.Minimum Then
                value = Me.Minimum
            ElseIf value > Me.Maximum Then
                value = Me.Maximum
            End If

            MyBase.Value = value
            RaiseEvent ValueChanged(Me)
            Me.Invalidate()
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the style of the progress bar.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the style of the progress bar."), ComponentModel.DefaultValue(BrushBarStyle.Solid)> _
    Public Property BarStyle() As BrushBarStyle
        Get
            Return _BarStyle
        End Get
        Set(ByVal value As BrushBarStyle)
            _BarStyle = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the progress bar color.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the progress bar color"), ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "Highlight")> _
    Public Overrides Property ForeColor() As System.Drawing.Color
        Get
            Return MyBase.ForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            MyBase.ForeColor = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the back color of the progress bar.  This is used with Gradient style progress bars.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the back color of the progress bar.  This is used with Gradient style progress bars."), ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "Control"), ComponentModel.Browsable(True)> _
    Public Overrides Property BackColor() As System.Drawing.Color
        Get
            Return _BackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            _BackColor = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the color of the control.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the the color of the control."), ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "Control")> _
    Public Property ControlColor() As System.Drawing.Color
        Get
            Return MyBase.BackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            MyBase.BackColor = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets a picture that will be used instead of a color to show progress.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets a picture that will be used instead of a color to show progress.")> _
    Public Property Picture() As System.Drawing.Image
        Get
            Return _Picture
        End Get
        Set(ByVal value As System.Drawing.Image)
            _Picture = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the text to be displayed when the TextStyle is set to DefaultText.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the text to be displayed when the TextStyle is set to DefaultText."), System.ComponentModel.Browsable(True)> _
    Public Overrides Property Text() As String
        Get
            Return MyBase.Text
        End Get
        Set(ByVal value As String)
            MyBase.Text = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the TextStyle used when outputting text.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the TextStyle used when outputting text."), ComponentModel.DefaultValue(BarTextStyle.DefaultText)> _
    Public Property TextStyle() As BarTextStyle
        Get
            Return _TextStyle
        End Get
        Set(ByVal value As BarTextStyle)
            _TextStyle = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the properties of the font used.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Browsable(True)> _
    Public Overrides Property Font() As System.Drawing.Font
        Get
            Return _Font
        End Get
        Set(ByVal value As System.Drawing.Font)
            _Font = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the font color for the text displayed.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets the font color for the text displayed."), ComponentModel.DefaultValue(GetType(System.Drawing.SystemColors), "WindowText")> _
    Public Property FontColor() As System.Drawing.Color
        Get
            Return _FontColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            _FontColor = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets if the text should highlight as the progress bar crosses the text.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets if the text should highlight as the progress bar crosses the text."), ComponentModel.DefaultValue(True)> _
    Public Property AllowFontHighlight() As Boolean
        Get
            Return _AllowFontHighlight
        End Get
        Set(ByVal value As Boolean)
            _AllowFontHighlight = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets if the size of the font should adjust depending on the size of the control.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("Sets if the size of the font should adjust depending on the size of the control."), ComponentModel.DefaultValue(True)> _
    Public Property FontAutoSize() As Boolean
        Get
            Return _FontAutoAdjust
        End Get
        Set(ByVal value As Boolean)
            _FontAutoAdjust = value
        End Set
    End Property
#End Region

#Region "Events"
    Public Event ValueChanged(ByVal sender As Object)
    'Public Sub cpm_ValueChanged(ByVal sender As Object)
    '    If Me IsNot Nothing Then
    '        Me.CreateGraphics.Clear(Me.ControlColor)
    '        PaintBar(Me.CreateGraphics)
    '        PaintText(Me.CreateGraphics)

    '        'Me.Invalidate()
    '    End If

    '    RaiseEvent ValueChanged(sender)
    'End Sub
#End Region

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        e.Graphics.Clear(Me.ControlColor)

        If Me IsNot Nothing Then
            PaintBar(e.Graphics)
            PaintText(e.Graphics)
        End If

        MyBase.OnPaint(e)
    End Sub

    'Paint a bar graphic to the control
    Private Sub PaintBar(ByVal sender As System.Drawing.Graphics)
        'If text is painted then a bar must be painted as it will no longer show on its own.
        Dim percentage As Double = (Me.Value / Me.Maximum * Me.ClientRectangle.Width)
        Dim rect As New System.Drawing.RectangleF(Me.ClientRectangle.X, Me.ClientRectangle.Y, percentage, Me.ClientRectangle.Height)
        Dim BarBrush As System.Drawing.Brush

        Select Case _BarStyle
            Case BrushBarStyle.Block
                BarBrush = New System.Drawing.Drawing2D.HatchBrush(Drawing.Drawing2D.HatchStyle.Vertical, Me.ControlColor, Me.ForeColor)
            Case BrushBarStyle.GradientHorizontal
                If percentage > 0 Then BarBrush = New System.Drawing.Drawing2D.LinearGradientBrush(rect, Me.ForeColor, Me.BackColor, Drawing.Drawing2D.LinearGradientMode.Horizontal)
            Case BrushBarStyle.GradientVertical
                If percentage > 0 Then BarBrush = New System.Drawing.Drawing2D.LinearGradientBrush(rect, Me.ForeColor, Me.BackColor, Drawing.Drawing2D.LinearGradientMode.Vertical)
            Case BrushBarStyle.Solid
                BarBrush = New System.Drawing.SolidBrush(Me.ForeColor)
            Case BrushBarStyle.Picture
                If _Picture IsNot Nothing Then BarBrush = New System.Drawing.TextureBrush(_Picture, Drawing.Drawing2D.WrapMode.Tile)
        End Select

        If BarBrush Is Nothing Then BarBrush = New System.Drawing.SolidBrush(Me.ForeColor)

        sender.SmoothingMode = Drawing.Drawing2D.SmoothingMode.Default
        sender.FillRectangle(BarBrush, rect)
        BarBrush.Dispose()
    End Sub

    'Paint text to the control
    Private Sub PaintText(ByVal sender As System.Drawing.Graphics)
        Dim x As Decimal 'Double 'Integer 'Single
        Dim y As Decimal 'Double 'Integer 'Single
        Dim text As String = " "
        Dim sizeF As System.Drawing.SizeF

        Select Case Me.TextStyle
            Case BarTextStyle.DefaultText
                text = Me.Text
            Case BarTextStyle.ValueText
                text = Me.Value
            Case BarTextStyle.ValueOfMax
                text = Me.Value & "/" & Me.Maximum & " " & Me.Font.Size & "/" & Me.Font.Size
            Case BarTextStyle.PercentText
                text = (Me.Value / Me.Maximum * 100)
        End Select

        'sizeF = Me.CreateGraphics.MeasureString(text, Me.Font, Me.Width)
        sizeF = Me.CreateGraphics.MeasureString(text, Me.Font, Len(text) * Me.Font.SizeInPoints)
        If Me.FontAutoSize = True Then
            If sizeF.ToSize.Height < Me.ClientRectangle.Height - 5 Then sizeF = FontAdjust(sizeF)
        End If

        x = (Me.ClientRectangle.Width / 2) - (sizeF.ToSize.Width / 2)
        y = (Me.ClientRectangle.Height / 2) - (sizeF.ToSize.Height / 2)

        'Dim TextFormat As New System.Drawing.StringFormat
        'TextFormat.Alignment = Drawing.StringAlignment.Center
        'TextFormat.LineAlignment = Drawing.StringAlignment.Center

        Dim percentage As Double = (Me.Value / Me.Maximum * Me.ClientRectangle.Width)

        ''Dim TempColor As System.Drawing.Color
        ''If percentage > (x + sizeF.ToSize.Width) Then
        ''    TempColor = System.Drawing.SystemColors.HighlightText
        ''Else
        ''    TempColor = Me.FontColor
        ''End If
        'sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(Me.FontColor), x, y)
        sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(Me.FontColor), New System.Drawing.RectangleF(x, y, sizeF.Width, sizeF.Height))


        'If percentage > x And percentage < (x + sizeF.ToSize.Width) Then
        'Dim InText As Integer = Math.Ceiling((percentage - x) / text.Length)
        'Dim Text1 As String = text.Substring(0, InText)
        If Me.AllowFontHighlight = True Then

            sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(System.Drawing.SystemColors.HighlightText), New System.Drawing.RectangleF(x, y, (percentage - x) + 2, sizeF.Height))
        End If
        'sender.DrawString(text, Me.Font, New System.Drawing.SolidBrush(System.Drawing.SystemColors.HighlightText), New System.Drawing.RectangleF(Me.ClientRectangle.X, Me.ClientRectangle.Y, (percentage - x), Me.ClientRectangle.Height))
        'End If
    End Sub

    Private Function FontAdjust(ByVal Size As System.Drawing.SizeF) As System.Drawing.SizeF
        Dim sizeF As System.Drawing.SizeF = Me.CreateGraphics.MeasureString(Text, Me.Font, Me.ClientRectangle.Width)

        If sizeF.ToSize.Height < Me.ClientRectangle.Height - 5 Or sizeF.ToSize.Height > Me.ClientRectangle.Height Then
            If Me.ClientRectangle.Height > 2 Then
                sizeF = New System.Drawing.SizeF(sizeF.Width, Me.ClientRectangle.Height)
                Me.Font = New System.Drawing.Font(Me.Font.FontFamily, Me.ClientRectangle.Height, Me.Font.Style, Drawing.GraphicsUnit.Pixel)
                Return sizeF
            End If
        End If

        Return sizeF
    End Function

End Class

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Sorwen, I produced a ProgressBar control a while ago that I think does what you want. Unfortunately, I am working away from home and won't be able to get it before the weekend.

If you are interested let me know.
 
When you can. Any input would be appreciated.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
This is "chopped down" version of the ProgressBar, that incorporates the important parts as far as your requirements are concerned.

It does not inherit from ProgressBar, instead it is created from scratch, so you may need to make some additional changes.

I hope you find it useful. I haven't included many comments, however I don't think that that will cause any undue problems.


Code:
Imports System.ComponentModel

Public Class ProgBar

	Private FValue As Integer = 0
	Private FMaximum As Integer = 100
	Private FMinimum As Integer = 0
	Private FIncrement As Integer = 1
	Private FFillColor As Color = Color.RoyalBlue
	Private FTextColor As Color = Color.Black
	Private FTextHighlight As Color = Color.White
	Private FBorderStyle As BorderStyle = Windows.Forms.BorderStyle.FixedSingle

	<DefaultValue(0)> _
 Public Property Value() As Integer
		Get
			Return FValue
		End Get
		Set(ByVal value As Integer)
			If value >= FMinimum AndAlso value <= FMaximum Then
				FValue = value
				Invalidate()
			Else
				Throw New ArgumentOutOfRangeException("Value must be between Minimum and Maximum")
			End If
		End Set
	End Property

	<DefaultValue(100)> _
 Public Property Maximum() As Integer
		Get
			Return FMaximum
		End Get
		Set(ByVal value As Integer)
			If value > FMinimum Then
				FMaximum = value
			Else
				Throw New ArgumentOutOfRangeException("Maximum must be greater than Minimum")
			End If
		End Set
	End Property

	<DefaultValue(0)> _
 Public Property Minimum() As Integer
		Get
			Return FMinimum
		End Get
		Set(ByVal value As Integer)
			If value < FMaximum Then
				FMinimum = value
			Else
				Throw New ArgumentOutOfRangeException("Minimum must be less then Maximum")
			End If
		End Set
	End Property

	<DefaultValue(1)> _
 Public Property Increment() As Integer
		Get
			Return FIncrement
		End Get
		Set(ByVal value As Integer)
			FIncrement = value
		End Set
	End Property

	<DefaultValue(GetType(Color), "RoyalBlue")> _
 Public Property FillColor() As Color
		Get
			Return FFillColor
		End Get
		Set(ByVal value As Color)
			FFillColor = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Color), "Black")> _
 Public Property TextColor() As Color
		Get
			Return FTextColor
		End Get
		Set(ByVal value As Color)
			FTextColor = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Color), "White")> _
	Public Property TextHighlight() As Color
		Get
			Return FTextHighlight
		End Get
		Set(ByVal value As Color)
			FTextHighlight = value
		End Set
	End Property

	<DefaultValue(GetType(Windows.Forms.BorderStyle), "FixedSingle")> _
 Public Property BorderStyle() As BorderStyle
		Get
			Return FBorderStyle
		End Get
		Set(ByVal value As BorderStyle)
			FBorderStyle = value
			RecreateHandle()
			Invalidate()
		End Set
	End Property

	<Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _
	Public Shadows Property Text() As String
		Get
			Return MyBase.Text
		End Get
		Set(ByVal value As String)
			'Do nothing.
			'Setting this to readonly causes the designer to complain because it tries to set the text property.
			'This way, we can still use this property but the user & designer can't mess with it.
		End Set
	End Property

	Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
		'Add BorderStyle
		Get
			Const WS_BORDERSTYLE As Integer = &H800000L
			Const WS_EX_STATICEDGE As Integer = &H20000
			Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
			Select Case FBorderStyle
				Case Windows.Forms.BorderStyle.FixedSingle
					cp.Style = cp.Style Or WS_BORDERSTYLE
				Case Windows.Forms.BorderStyle.Fixed3D
					cp.ExStyle = cp.ExStyle Or WS_EX_STATICEDGE
			End Select
			Return cp
		End Get
	End Property

	Public Overloads Sub PerformStep()

		PerformStep(FIncrement)

	End Sub

	Public Overloads Sub PerformStep(ByVal Distance As Integer)

		If Distance < 0 Then
			If FValue + Distance < FMinimum Then FValue = Minimum Else FValue += Distance
		ElseIf Distance > 0 Then
			If FValue + Distance > FMaximum Then FValue = FMaximum Else FValue += Distance
		Else
			'No need to do anything as 0 has to be added to / subtracted from FValue
		End If

		Invalidate()

	End Sub

	Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

		'This line seems to have no effect (whether or not it is used).
		'I've included it because it is recommended practice...
		MyBase.OnPaint(e)

		Dim g As Graphics = e.Graphics
		g.FillRectangle(New SolidBrush(FFillColor), New Rectangle(0, 0, CInt(CDec(FValue / FMaximum * Width)), Height))
		MyBase.Text = FValue.ToString + " of " + FMaximum.ToString
		Dim ssize As SizeF = e.Graphics.MeasureString(Text, Font)
		Dim x1 As Integer = (Width - CInt(ssize.Width)) \ 2
		Dim y1 As Integer = (Height - CInt(ssize.Height)) \ 2
		g.DrawString(Text, Font, New SolidBrush(FTextColor), x1, y1)
		Dim rf As Rectangle
		rf.X = x1
		rf.Y = y1
		rf.Height = CInt(ssize.Height)
		rf.Width = (CInt(CDec(FValue / FMaximum * Width))) - x1
		g.SetClip(rf)
		g.DrawString(Text, Font, New SolidBrush(FTextHighlight), x1, y1)

	End Sub

End Class

and the designer code:

Code:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class ProgBar
	Inherits System.Windows.Forms.Control

	'Control overrides dispose to clean up the component list.
	<System.Diagnostics.DebuggerNonUserCode()> _
	Protected Overrides Sub Dispose(ByVal disposing As Boolean)
		Try
			If disposing AndAlso components IsNot Nothing Then
				components.Dispose()
			End If
		Finally
			MyBase.Dispose(disposing)
		End Try
	End Sub

	'Required by the Control Designer
	Private components As System.ComponentModel.IContainer

	' NOTE: The following procedure is required by the Component Designer
	' It can be modified using the Component Designer.  Do not modify it
	' using the code editor.
	<System.Diagnostics.DebuggerStepThrough()> _
	Private Sub InitializeComponent()
		components = New System.ComponentModel.Container()
	End Sub

End Class
 
Having read through your code, I've extracted some more from mine.

Unfortunately mine is part of a control library with 20 or more controls. As such there is a lot of shared functionality among the controls and it has not been as easy as I thought to pick out everything for the progress bar.

A number of the properties don't make sense when others are set, and as such I have a number of TypeConverters etc. to handle this in the PropertyGrid. I'm not sure when I will have time to "untangle" them. The controls make extensive use of base classes and supporting classes within the library, and as such it has not been easy to pick out all the bits.

I've also tried to tidy up the extracted code a liitle to make it easier to read.

The designer's Partial Class is as I posted last night.

Code:
Imports System.ComponentModel
Imports System.Drawing.Drawing2D

Public Class ProgBar

	Public Enum ProgressBarFillStyle
		Solid
		Hatch
		Gradient
		Image
	End Enum

	Public Enum ProgressBarTextParts
		Start
		Join
		[End]
		ValueUnit
		MaximumUnit
		Value
		Maximum
		Minimum
		Percentage
		ZeroText
	End Enum

	Private FValue As Integer = 0
	Private FMaximum As Integer = 100
	Private FMinimum As Integer = 0
	Private FIncrement As Integer = 1

	Private FFillStyle As ProgressBarFillStyle = ProgressBarFillStyle.Solid
	Private FImage As Image = Nothing
	Private FHatchStyle As HatchStyle = HatchStyle.DarkDownwardDiagonal
	Private FGradientStyle As LinearGradientMode = LinearGradientMode.ForwardDiagonal
	Private FFillColorStart As Color = Color.RoyalBlue
	Private FFillColorEnd As Color = Color.LightCyan

	Private FTextColor As Color = Color.Black
	Private FTextHighlight As Color = Color.White

	Private FTextParts() As ProgressBarTextParts = _
	 {ProgressBarTextParts.Value, ProgressBarTextParts.Join, ProgressBarTextParts.Maximum, ProgressBarTextParts.MaximumUnit, ProgressBarTextParts.ZeroText}
	Private FStartText As String = ""
	Private FJoinText As String = " of "
	Private FEndText As String = ""
	Private FUnitsSingular As String = ""
	Private FUnitsPlural As String = ""
	Private FZeroText As String = ""

	Private FBorderStyle As BorderStyle = BorderStyle.FixedSingle

	<DefaultValue(0)> _
 Public Property Value() As Integer
		Get
			Return FValue
		End Get
		Set(ByVal value As Integer)
			If value >= FMinimum AndAlso value <= FMaximum Then
				FValue = value
				Invalidate()
			Else
				Throw New ArgumentOutOfRangeException("Value must be between Minimum and Maximum")
			End If
		End Set
	End Property

	<DefaultValue(100)> _
	Public Property Maximum() As Integer
		Get
			Return FMaximum
		End Get
		Set(ByVal value As Integer)
			If value > FMinimum AndAlso value >= FValue Then
				FMaximum = value
				Invalidate()
			Else
				Throw New ArgumentOutOfRangeException("Maximum must be greater than Minimum and greater than or equal to current Value")
			End If
		End Set
	End Property

	<DefaultValue(0)> _
	Public Property Minimum() As Integer
		Get
			Return FMinimum
		End Get
		Set(ByVal value As Integer)
			If value < FMaximum AndAlso value <= FValue Then
				FMinimum = value
				Invalidate()
			Else
				Throw New ArgumentOutOfRangeException("Minimum must be less then Maximum and less than or equal to current Value")
			End If
		End Set
	End Property

	<DefaultValue(1)> _
	Public Property Increment() As Integer
		Get
			Return FIncrement
		End Get
		Set(ByVal value As Integer)
			FIncrement = value
		End Set
	End Property

	<DefaultValue(GetType(ProgressBarFillStyle), "Solid")> _
 Public Property FillStyle() As ProgressBarFillStyle
		Get
			Return FFillStyle
		End Get
		Set(ByVal value As ProgressBarFillStyle)
			FFillStyle = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(HatchStyle), "DarkDownwardDiagonal"), Browsable(True)> _
 Public Property HatchStyle() As HatchStyle
		Get
			Return FHatchStyle
		End Get
		Set(ByVal value As HatchStyle)
			FHatchStyle = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(LinearGradientMode), "ForwardDiagonal"), Browsable(True)> _
 Public Property GradientStyle() As LinearGradientMode
		Get
			Return FGradientStyle
		End Get
		Set(ByVal value As LinearGradientMode)
			FGradientStyle = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Color), "RoyalBlue")> _
	Public Property FillColorStart() As Color
		Get
			Return FFillColorStart
		End Get
		Set(ByVal value As Color)
			FFillColorStart = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Color), "LightCyan")> _
 Public Property FillColorEnd() As Color
		Get
			Return FFillColorEnd
		End Get
		Set(ByVal value As Color)
			FFillColorEnd = value
			Invalidate()
		End Set
	End Property

	<Browsable(True)> _
 Public Property Image() As Image
		Get
			Return FImage
		End Get
		Set(ByVal value As Image)
			FImage = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Color), "Black")> _
 Public Property TextColor() As Color
		Get
			Return FTextColor
		End Get
		Set(ByVal value As Color)
			FTextColor = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Color), "White")> _
	Public Property TextHighlight() As Color
		Get
			Return FTextHighlight
		End Get
		Set(ByVal value As Color)
			FTextHighlight = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(GetType(Windows.Forms.BorderStyle), "FixedSingle")> _
	Public Property BorderStyle() As BorderStyle
		Get
			Return FBorderStyle
		End Get
		Set(ByVal value As BorderStyle)
			FBorderStyle = value
			RecreateHandle()
			Invalidate()
		End Set
	End Property

	<Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _
	Public Shadows Property Text() As String
		Get
			Return MyBase.Text
		End Get
		Set(ByVal value As String)
			'Do nothing.
			'Setting this to readonly causes the designer to complain because it tries to set the text property.
			'This way, we can still use this property but the user & designer can't mess with it.
		End Set
	End Property

	<DefaultValue(GetType(ProgressBarTextParts), "Value, Join, Maximum, MaximumUnit, ZeroText")> _
 Public Property TextParts() As ProgressBarTextParts()
		Get
			Return FTextParts
		End Get
		Set(ByVal value As ProgressBarTextParts())
			FTextParts = value
			Invalidate()
		End Set
	End Property

	<DefaultValue("")> _
 Public Property StartText() As String
		Get
			Return FStartText
		End Get
		Set(ByVal value As String)
			FStartText = value
			Invalidate()
		End Set
	End Property

	<DefaultValue(" of ")> _
 Public Property JoinText() As String
		Get
			Return FJoinText
		End Get
		Set(ByVal value As String)
			FJoinText = value
			Invalidate()
		End Set
	End Property

	<DefaultValue("")> _
 Public Property EndText() As String
		Get
			Return FEndText
		End Get
		Set(ByVal value As String)
			FEndText = value
			Invalidate()
		End Set
	End Property

	<DefaultValue("")> _
 Public Property UnitsSingular() As String
		Get
			Return FUnitsSingular
		End Get
		Set(ByVal value As String)
			FUnitsSingular = value
			Invalidate()
		End Set
	End Property

	<DefaultValue("")> _
 Public Property UnitsPlural() As String
		Get
			Return FUnitsPlural
		End Get
		Set(ByVal value As String)
			FUnitsPlural = value
			Invalidate()
		End Set
	End Property

	<DefaultValue("")> _
 Public Property ZeroText() As String
		Get
			Return FZeroText
		End Get
		Set(ByVal value As String)
			FZeroText = value
			Invalidate()
		End Set
	End Property

	Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
		'Add BorderStyle
		Get
			Const WS_BORDERSTYLE As Integer = &H800000L
			Const WS_EX_STATICEDGE As Integer = &H20000
			Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
			Select Case FBorderStyle
				Case Windows.Forms.BorderStyle.FixedSingle
					cp.Style = cp.Style Or WS_BORDERSTYLE
				Case Windows.Forms.BorderStyle.Fixed3D
					cp.ExStyle = cp.ExStyle Or WS_EX_STATICEDGE
			End Select
			Return cp
		End Get
	End Property

	Public Overloads Sub PerformStep()

		PerformStep(FIncrement)

	End Sub

	Public Overloads Sub PerformStep(ByVal Distance As Integer)

		If Distance < 0 Then
			If FValue + Distance < FMinimum Then FValue = Minimum Else FValue += Distance
		ElseIf Distance > 0 Then
			If FValue + Distance > FMaximum Then FValue = FMaximum Else FValue += Distance
		Else
			'No need to do anything as 0 has to be added to / subtracted from FValue
		End If
		Invalidate()

	End Sub

	Private Function GetBrush(ByVal r As Rectangle) As Brush

		Select Case FFillStyle
			Case ProgressBarFillStyle.Hatch
				Return New HatchBrush(FHatchStyle, FFillColorStart, FFillColorEnd)
			Case ProgressBarFillStyle.Gradient
				Return New LinearGradientBrush(r, FFillColorStart, FFillColorEnd, FGradientStyle)
			Case ProgressBarFillStyle.Image
				If FImage IsNot Nothing Then
					Return New System.Drawing.TextureBrush(FImage, Drawing.Drawing2D.WrapMode.Tile)
				Else
					Return New SolidBrush(FFillColorStart)
				End If
			Case Else
				Return New SolidBrush(FFillColorStart)
		End Select

	End Function

	Private Function GetText() As String

		Dim s As String = ""
		Dim ZeroTextFlag As Boolean = False
		For a As Integer = 0 To FTextParts.Length - 1
			Select Case FTextParts(a)
				Case ProgressBarTextParts.End
					s += FEndText
				Case ProgressBarTextParts.Join
					s += FJoinText
				Case ProgressBarTextParts.Maximum
					s += FMaximum.ToString
				Case ProgressBarTextParts.MaximumUnit
					s += If(FMaximum > 1, FUnitsPlural, FUnitsSingular)
				Case ProgressBarTextParts.Minimum
					s += FMinimum.ToString
				Case ProgressBarTextParts.Percentage
					s += (FValue * 100 \ FMaximum).ToString
				Case ProgressBarTextParts.Start
					s += FStartText
				Case ProgressBarTextParts.Value
					s += FValue.ToString
				Case ProgressBarTextParts.ValueUnit
					s += If(FValue > 1, FUnitsPlural, FUnitsSingular)
				Case ProgressBarTextParts.ZeroText
					ZeroTextFlag = True
			End Select
		Next
		If ZeroTextFlag AndAlso FValue = 0 Then s = FZeroText
		Return s

	End Function

	Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

		'This line seems to have no effect (whether or not it is used).
		'I've included it because it is recommended practice...
		MyBase.OnPaint(e)

		Dim g As Graphics = e.Graphics
		Dim r As Rectangle
		If FValue > 0 Then
			r = New Rectangle(0, 0, CInt(CDec(FValue / FMaximum * Width)), Height)
			g.FillRectangle(GetBrush(r), r)
		End If
		MyBase.Text = GetText()
		Dim ssize As SizeF = e.Graphics.MeasureString(Text, Font)
		Dim x1 As Integer = (Width - CInt(ssize.Width)) \ 2
		Dim y1 As Integer = (Height - CInt(ssize.Height)) \ 2
		g.DrawString(Text, Font, New SolidBrush(FTextColor), x1, y1)
		r.X = x1
		r.Y = y1
		r.Height = CInt(ssize.Height)
		r.Width = (CInt(CDec(FValue / FMaximum * Width))) - x1
		g.SetClip(r)
		g.DrawString(Text, Font, New SolidBrush(FTextHighlight), x1, y1)

	End Sub

End Class
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top