We help IT Professionals succeed at work.

Check out this week's podcast, "Dairy Farms to Databases: Community's Hand in Technology"Listen Now

x

Create a progress bar for timer

459 Views
Last Modified: 2014-12-17
Hi EE,

In VB.NET, I would like to have on my form a progress bar that decreases.
Lets say I tell the form that the timer is 4 minutes.. I would like the progress abr to decreases to zero at 4mins and it would start Green and going yellow up to red once the timer reaches lets say 3mins or 1/3 left...

can you help me ?

Either a bar or a kind of circle like a clock with a line going clockwise
Comment
Watch Question

AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
There is a ProgressBar control - put one onto your form.

Have a look at the following:
http://msdn.microsoft.com/en-us/library/system.windows.forms.progressbar.maximum%28v=vs.110%29.aspx

Set the max and minimum values to 240 and 0 (seconds in 4 minutes, try a step of -1 to decrement) then do the PerformStep in your timer event - I assume you wanted a step per second with the above values.
CERTIFIED EXPERT
Most Valuable Expert 2011
Top Expert 2015
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009

Commented:
This is pared down and modified code from my "Kids Alarm Clock" project, which I demonstrate here:
https://www.youtube.com/watch?v=qucWOkZp0Uw
Full Source Code:
http://dl.dropbox.com/u/5131616/KidAlarmClockProject%28Source%29.zip

Obviously this doesn't do exactly what you described, but I thought you might be interested in the parts of the code that draw the circular portions.  They represent how much time is left until the alarm goes off.  The outer red band is how many hours are left.  The middle blue band is how many minutes is left.  The inner green band is how many seconds are left.  In this image, there is 5 hours, 36 minutes, and 15 seconds left:
5 hours, 36 minutes, 15 seconds left
CircularCountdownTimer UserControl:
Public Class CircularCountdownTimer

    Private Const OuterHourDistance As Double = 0.98
    Private Const InnerHourDistance As Double = 0.78

    Private Const OuterMinuteDistance As Double = 0.68
    Private Const InnerMinuteDistance As Double = 0.48

    Private Const OuterSecondDistance As Double = 0.38
    Private Const InnerSecondDistance As Double = 0.18

    ' The Target Time to stop at:
    Private _StopHour As Integer ' 0 to 23
    Private _StopMinute As Integer ' 0 to 59
    Private _StopSecond As Integer ' ' 0 to 59

    Private ReadOnly Property Time() As TimeSpan
        Get
            Return New TimeSpan(Me._StopHour, Me._StopMinute, Me._StopSecond)
        End Get
    End Property

    Public Sub SetDuration(ByVal TS As TimeSpan)
        Dim StopTime As DateTime = DateTime.Now.Add(TS)
        _StopHour = StopTime.TimeOfDay.Hours
        _StopMinute = StopTime.TimeOfDay.Minutes
        _StopSecond = StopTime.TimeOfDay.Seconds
        Me.Refresh()
    End Sub

    Private WithEvents Tmr As System.Windows.Forms.Timer

    Private Sub CircularCountdownTimer_Load(sender As Object, e As EventArgs) Handles Me.Load
        ' Double Buffered to reduce flicker
        Me.SetStyle(ControlStyles.UserPaint, True)
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(ControlStyles.DoubleBuffer, True)
        Me.SetStyle(ControlStyles.ResizeRedraw, True)
        Me.UpdateStyles()

        Tmr = New System.Windows.Forms.Timer
        Tmr.Interval = 1000
        Tmr.Enabled = True
    End Sub

    Private Sub Tmr_Tick(sender As Object, e As EventArgs) Handles Tmr.Tick
        Me.Refresh()
    End Sub

    Private Sub CircularCountdownTimer_Resize(sender As Object, e As EventArgs) Handles Me.Resize
        Me.Refresh()
    End Sub

    Private Sub CircularCountdownTimer_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        Dim C As Color
        Dim cx As Single = Me.Width / 2
        Dim cy As Single = Me.Height / 2
        Dim SmallerDimension = Math.Min(Me.Width, Me.Height)
        Dim innerDistance, outerDistance As Single

        Static hourList As New List(Of Point)
        Static prevHour As Integer = -1
        Static minList As New List(Of Point)
        Static prevMin As Integer = -1
        Static secList As New List(Of Point)
        Static prevSec As Integer = -1

        Dim ts As TimeSpan = Me.CalcKillTime.Subtract(DateTime.Now)
        Dim startAngle As Integer = GetHourAngle(12)
        Dim stopAngle As Integer
        Dim ps() As Point

        If ts.Hours >= 1 Then
            C = Color.Red
            stopAngle = GetMinuteAngle(ts.Hours * 5)
            If stopAngle <> prevHour Then
                outerDistance = SmallerDimension * OuterHourDistance / 2
                innerDistance = SmallerDimension * InnerHourDistance / 2
                BuildTimeSlice(hourList, cx, cy, stopAngle, innerDistance, outerDistance)
                prevHour = stopAngle
            End If
            ps = hourList.ToArray
            Using hb As New Drawing2D.HatchBrush(Drawing2D.HatchStyle.Percent10, Color.Black, C)
                e.Graphics.FillPolygon(hb, ps)
            End Using
            e.Graphics.DrawLines(Pens.Black, ps)
        End If
        If ts.Minutes > 0 Then
            C = Color.Blue
            stopAngle = GetMinuteAngle(ts.Minutes)
            If stopAngle <> prevMin Then
                outerDistance = SmallerDimension * OuterMinuteDistance / 2
                innerDistance = SmallerDimension * InnerMinuteDistance / 2
                BuildTimeSlice(minList, cx, cy, stopAngle, innerDistance, outerDistance)
                prevHour = stopAngle
            End If
            ps = minList.ToArray
            Using hb As New Drawing2D.HatchBrush(Drawing2D.HatchStyle.Percent10, Color.Black, C)
                e.Graphics.FillPolygon(hb, ps)
            End Using
            e.Graphics.DrawLines(Pens.Black, ps)
        End If
        If ts.Seconds > 0 Then
            C = Color.LightGreen
            stopAngle = GetMinuteAngle(ts.Seconds)
            If stopAngle <> prevMin Then
                outerDistance = SmallerDimension * OuterSecondDistance / 2
                innerDistance = SmallerDimension * InnerSecondDistance / 2
                BuildTimeSlice(secList, cx, cy, stopAngle, innerDistance, outerDistance)
                prevHour = stopAngle
            End If
            ps = secList.ToArray
            Using hb As New Drawing2D.HatchBrush(Drawing2D.HatchStyle.Percent10, Color.Black, C)
                e.Graphics.FillPolygon(hb, ps)
            End Using
            e.Graphics.DrawLines(Pens.Black, ps)
        End If
    End Sub

    Private Sub BuildTimeSlice(ByVal pList As List(Of Point), _
                               ByVal cx As Single, ByVal cy As Single, ByVal MinuteAngle As Integer, _
                               ByVal innerDistance As Single, ByVal outerDistance As Single)
        pList.Clear()
        pList.Add(GetPoint(cx, cy, 360, outerDistance))
        For i As Integer = 360 To MinuteAngle Step -6
            pList.Add(GetPoint(cx, cy, i, outerDistance))
            If i Mod 30 = 0 Then
                pList.Add(GetPoint(cx, cy, i, innerDistance))
                pList.Add(GetPoint(cx, cy, i, outerDistance))
            End If
        Next
        pList.Add(GetPoint(cx, cy, MinuteAngle, innerDistance))
        For i As Integer = MinuteAngle To 360 Step 6
            pList.Add(GetPoint(cx, cy, i, innerDistance))
        Next
        pList.Add(GetPoint(cx, cy, 360, outerDistance))
    End Sub

    Private Function GetHourAngle(ByVal hour As Integer) As Integer
        hour = IIf(hour = 0, 12, IIf(hour <= 12, hour, hour - 12))
        Return (-hour + 12) * 30
    End Function

    Private Function GetMinuteAngle(ByVal minute As Integer) As Integer
        Return -6 * (minute - 60)
    End Function

    Private Function GetPoint(ByVal cx As Single, ByVal cy As Single, ByVal angleInDegrees As Single, ByVal distance As Single) As Point
        ' angleInDegrees
        ' Valid values are 0 --> 359 (six degrees = one minute on clock)
        ' draw a line from the center of the circle:
        ' 0 = up
        ' 90 = left
        ' 180 = down
        ' 270 = right

        ' Offset and Invert Angle then Convert Degrees to Radians
        angleInDegrees = -(angleInDegrees + 90) * Math.PI / 180

        ' Compute the point that is at the specified angle from horizontal and at the specifed distance
        Return New Point(cx + distance * Math.Cos(angleInDegrees), cy + distance * Math.Sin(angleInDegrees))
    End Function

    Public Function CalcKillTime() As DateTime
        Dim AM As Boolean = DateTime.Now.Hour < 12
        Dim ts As TimeSpan = Me.Time
        If AM Then
            If DateTime.Now.Hour = 0 AndAlso Me.Time.Hours = 12 Then
                If DateTime.Now.Minute < ts.Minutes Then
                    Return DateTime.Today.AddMinutes(ts.Minutes)
                End If
            ElseIf ts < DateTime.Now.TimeOfDay Then
                ts = ts.Add(New TimeSpan(12, 0, 0))
            End If
            Return DateTime.Today.Add(ts)
        Else
            If ts.Hours = 12 Then
                If DateTime.Now.Hour = 12 Then
                    If ts > DateTime.Now.TimeOfDay Then
                        Return DateTime.Today.Add(ts)
                    End If
                End If
                Return DateTime.Today.AddDays(1).AddMinutes(ts.Minutes)
            Else
                ts = New TimeSpan(ts.Hours + 12, ts.Minutes, 0)
                If ts > DateTime.Now.TimeOfDay Then
                    Return DateTime.Today.Add(ts)
                Else
                    Return DateTime.Today.AddDays(1).Add(New TimeSpan(ts.Hours - 12, ts.Minutes, 0))
                End If
            End If
        End If
    End Function

End Class

Open in new window

Philippe RenaudVice President

Author

Commented:
Hi sorry for the long wait,
Thanks this is perfect

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.