954,535 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Flickering Issue in Graphic Repaint / Refresh

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

ashwinshenoy
Newbie Poster
18 posts since Apr 2011
Reputation Points: 10
Solved Threads: 0
 

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)
Oxiegen
Master Poster
715 posts since Jun 2006
Reputation Points: 87
Solved Threads: 141
 


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
Unhnd_Exception
Posting Pro
570 posts since Nov 2010
Reputation Points: 249
Solved Threads: 201
 

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

ashwinshenoy
Newbie Poster
18 posts since Apr 2011
Reputation Points: 10
Solved Threads: 0
 


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.

Unhnd_Exception
Posting Pro
570 posts since Nov 2010
Reputation Points: 249
Solved Threads: 201
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: