Hi Guys,

I have developed a program which continuously draws a circle using a timer. Now every time the circle gets displays it flickers and which is because i have used me.refresh. Is there any other way to avoid this flickering.

here is my code

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick

        Me.sweepAngle += 1


        If Me.sweepAngle = 360 Then

            Me.Timer1.Stop()
        End If

        If sweepAngle = 90 Then
            change = 1
        End If
        If sweepAngle = 180 Then
            change = 2
        End If
        'Me.Invalidate()
        Me.Refresh()
        'Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
       'Me.SetStyle(ControlStyles.UserPaint, True)
        'Me.SetStyle(ControlStyles.DoubleBuffer, True)

    End Sub

    Public Sub GroupBox1_Paint1(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles GroupBox1.Paint
        Dim a As Graphics = e.Graphics
        Dim mypen As Pen
        mypen = New Pen(System.Drawing.Color.Black, 2)
        'e.Graphics.DrawArc(Pens.Black, 10, 10, 48, 48, 0, Me.sweepAngle)
        a.DrawEllipse(mypen, 660, 20, 98, 98)
        e.Graphics.FillPie(Brushes.Red, 660, 20, 98, 98, -90, Me.sweepAngle)
        If change = 1 Then
            'e.Graphics.FillPie(Brushes.Green, 10, 20, 98, 98, -90, Me.sweepAngle)
            e.Graphics.FillPie(Brushes.Orange, New Rectangle(660, 20, 98, 98), -90, 90)
        End If
        If change = 2 Then
            e.Graphics.FillPie(Brushes.Orange, New Rectangle(660, 20, 98, 98), -90, 90)
            e.Graphics.FillPie(Brushes.Green, New Rectangle(660, 20, 98, 98), 0, 90)
        End If
    End Sub

Thank you
Ashwin

Recommended Answers

All 4 Replies

In the form load event, see if adding these three lines helps:

Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Member Avatar for Unhnd_Exception

You need to get rid of that Me.Refresh as well.

Your drawing on the groupbox so at most it should be GroupBox1.Refresh.

But you need to only repaint the area you are drawing.

Set up a global rectangle. And then call GroupBox1.Invalidate(global rectangle).

That will fix all most all your flickering alone.

Right now your redrawing the entire form just to draw a 100x100 circle.

Heres an example

'a global rectangle.  Set your x, y, and size here.
Private ClockRectangle As New Rectangle(0, 0, 100, 100)

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
    Me.sweepangle += 1

    If Me.sweepangle = 360 Then
        Me.Timer1.Stop()
    End If

    'Only redraw the rectangle. Not the entire form.
    GroupBox1.Invalidate(ClockRectangle)

    End Sub

Public Sub GroupBox1_Paint1(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles GroupBox1.Paint
         
    Dim mypen As Pen
    mypen = New Pen(System.Drawing.Color.Black, 2)

    'Change the smoothing mode so your circle looks better.
    e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
    e.Graphics.DrawEllipse(mypen, ClockRectangle)

    Select Case sweepangle
        Case 0 To 90
           e.Graphics.FillPie(Brushes.Red, ClockRectangle, -90, Me.sweepangle)
        Case 91 To 180
           e.Graphics.FillPie(Brushes.Red, ClockRectangle, -90, 90)
           e.Graphics.FillPie(Brushes.Orange, ClockRectangle, 0, Me.sweepangle - 90)
        Case 181 To 270
           e.Graphics.FillPie(Brushes.Red, ClockRectangle, -90, 90)
           e.Graphics.FillPie(Brushes.Orange, ClockRectangle, 0, 90)
           e.Graphics.FillPie(Brushes.Yellow, ClockRectangle, 90, Me.sweepangle - 180)
        Case 271 To 360
           e.Graphics.FillPie(Brushes.Red, ClockRectangle, -90, 90)
           e.Graphics.FillPie(Brushes.Orange, ClockRectangle, 0, 90)
           e.Graphics.FillPie(Brushes.Yellow, ClockRectangle, 90, 90)
           e.Graphics.FillPie(Brushes.Green, ClockRectangle, 180, Me.sweepangle - 270)
    End Select

    'Don't forget to dispose of your pens and brushes.
    mypen.Dispose()
End Sub

Thank you Unhend_Exception..
Your solution worked.. YOu have solved it so cleverly....
But sometime after 20 or 30 seconds... the clock does flicker and stops ... although it is ok... if you have any suggestions to amend the code then please lemme know.....

Thank you so much
ashwin

Member Avatar for Unhnd_Exception

The code Oxiegen provided should take care of it. Put it in the Load event or the New constructor of the form.

If you still have flickering problems. You can add a picture box to the group box and paint the circle in the picturebox's paint event. A picture box is double buffered by default, the panel class is not. You could set the picture box to the location and size you wanted the circle. That would eliminate the global rectangle. You could then call PictureBox1.Refresh to repaint and use PictureBox1.DisplayRectangle when drawing the rectangle. You will need to set the picturebox's size to 4 pixels wider and taller, set the padding to all = 2, and use DisplayRectangle instead of ClientRectangle when drawing. That will allow for a 2 pixel buffer for the antialiasing to fit.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.