Search code examples
vb.netwinformstimerpicturebox

How to create a timer on a new thread


I recently asked a question as to how I would get a vertical line to sweep from left to right across a Picturebox. There were shapes in the Picturebox and the vertical line had to indicate when it crossed one. I had an answer that worked great.

Private lineX As Integer = 0

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    lineX += 5

    If lineX > PictureBox1.Width Then
        lineX = 0
    End If

    PictureBox1.Invalidate()
End Sub

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    e.Graphics.DrawLine(Pens.Black,
                        New Point(lineX, 0),
                        New Point(lineX, PictureBox1.Height))
End Sub

However, I find that when I move the mouse around in the Picturebox, the vertical line stops, starts or slows down. From looking online, I think that a timer on a different thread might be the answer.

Could someone suggest a solution to this?


Solution

  • You could increase the accuracy of the movement by taking into account the effectively elapsed time:

    Private lineX As Integer = 0
    Private lastDateTime As Date?
    
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        PictureBox1.Invalidate()
    End Sub
    
    Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
        Dim now = Date.Now
        If lastDateTime.HasValue Then
            lineX += CInt(5 * (now - lastDateTime.Value).Milliseconds / Timer1.Interval)
        Else
            lineX += 5
        End If
        lastDateTime = now
    
        If lineX > PictureBox1.Width Then
            lineX = 0
        End If
        e.Graphics.DrawLine(Pens.Black,
                            New Point(lineX, 0),
                            New Point(lineX, PictureBox1.Height))
    End Sub
    

    Note that I moved the code changing the line position into the PictureBox1_Paint method to get the exact time at which the line is drawn.

    Painting can be delayed after PictureBox1.Invalidate() and painting can also occur in other situations, e.g., when the window is resized or moved around etc.

    Some calls to PictureBox1_Paint can even be dropped if the system is busy.

    Even after these changes the movement will not be perfect. WinForms is just not the right system for gaming like things.