|
-
Feb 9th, 2014, 01:44 PM
#1
Thread Starter
New Member
[RESOLVED] Drawing gdi+ flickering??? Heeeelp!
I have a Class which inherits a UserControl. The aim is to graphically display the sound input/output. The Property "Value" of Animation Class, receives the current value of the sound in realtime between 0 and 100, which i update from an outside Class via a Timer(50MSec.)
I managed it all to work but i am facing an annoying problem, the animation flickers. I raised the Thread.Priority into Highest, no effect, so i dont believe a separate Thread would do better. I researched and know now basically where the problem lies, but still cant figure out how to handle it. I have tried as in the beginning the ME.CreateGraphics Method, it flickered, then overrided OnPaint Method and painted with e.Graphics. The result was a blank control! Thanks for any help!
Here is a small demo of the code, an example
Code:
Public Class Form1
Private [DISPLAY] As Form 'A SEPARATE FORM THAT CONTAINS THE USERCONTROL "ANIMATION" & DISPLAYS IT
Private _Animation As Animation
Private Shadows Sub [load]() Handles MyBase.Load
DISPLAY = New Form
_Animation = New Animation
DISPLAY.Controls.Add(_Animation)
_Animation.Dock = DockStyle.Fill
DISPLAY.Show()
Dim tmr As New Timer(New System.ComponentModel.Container)
tmr.Interval = 50
AddHandler tmr.Tick, AddressOf Looper
tmr.Start()
End Sub
Private Sub Looper()
_Animation.Value = Now.Second 'AN EXAMPLE
End Sub
End Class
Public Class Animation
Inherits UserControl
Private _Value As UInt32
'EVERYTIME VALUE IS CHANGED IT WILL REPAINT THE CONTROL
Public Property Value As UInt32
Get
Return _Value
End Get
Set(ByVal value As UInt32)
_Value = value
[Refresh]()
End Set
End Property
Sub New()
' InitilizeComponent()
Countleds()
End Sub
Private LEDs As Integer
'COUNT THE AMOUNT OF LEDS POSSIBLE TO FIT IN CONTROL
Private Sub Countleds() Handles Me.SizeChanged
dictOfLeds.Clear()
LEDs = 0
If Me.Width < SizeCurrent Then
LEDs = 1
Else
Dim _MeWidth As Integer = Me.Width - SizeCurrent
LEDs = (_MeWidth \ (SizeOld + Space)) + 1
End If
For i As UInteger = 1 To LEDs Step +1
dictOfLeds.Add(i, 0)
Next
'MsgBox(LEDs)
End Sub
Private dictOfLeds As New Dictionary(Of UInt32, UInt16)
Private Space As Integer = 2
Private SizeCurrent = 7
Private SizeOld As Integer = 3
Private ColorOld As Brush = New SolidBrush(Color.Aqua)
Private ColorCurrent As Brush = New SolidBrush(Color.Blue)
Private _Pen As New Pen(Brushes.AliceBlue, 5.0F)
Private _StartPoint As New Point(0, 0)
Private _EndPoint As New Point(0, 0)
'THIS SUB WILL BE CALLED WHENEVER THE "[Value]" Property is changed
Private Shadows Sub [Refresh]()
For i = LEDs To 2 Step -1
If i = 2 Then dictOfLeds(1) = Value
dictOfLeds(i) = dictOfLeds(i - 1)
Next
Me.CreateGraphics.Clear(Color.Green)
Dim int As Integer
For i As Integer = 1 To LEDs Step +1
If i = 1 Then
int = (SizeCurrent \ 2) + Space
_Pen.Width = SizeCurrent
_Pen.Brush = ColorCurrent
ElseIf i = 2 Then
int = (SizeCurrent + Space) + ((SizeOld \ 2) + Space)
_Pen.Width = SizeOld
_Pen.Brush = ColorOld
ElseIf i > 2 Then
int += SizeOld + Space
_Pen.Width = SizeOld
_Pen.Brush = ColorOld
End If
Dim _location As New Point(0, CInt(Me.Height \ 2))
_StartPoint.X = (Me.Width) - int
_StartPoint.Y = (_location.Y - (Me.Height / 2) + dictOfLeds.Item(i))
_EndPoint.X = (Me.Width) - int
_EndPoint.Y = (_location.Y + (Me.Height \ 2) + (Me.Height / 2) + dictOfLeds.Item(i))
'Me.Invalidate() to raise Onpaint when painting via Onpaint
Me.CreateGraphics.DrawLine(_Pen, _StartPoint, _EndPoint)
Next
End Sub
Protected Overrides Sub Onpaint(Byval sender as Object, Byval e as painteventargs)
'WHEN PASSED THE e.graphics.drawline(_pen,_startpoint, _endpoint) result was nothing
End Sub
End Class
The result looks like this in my project (not the above code). the capture looks good but in reality it flickers while refreshing!
Last edited by Begi; Feb 9th, 2014 at 01:55 PM.
-
Feb 9th, 2014, 01:57 PM
#2
Re: Drawing gdi+ flickering??? Heeeelp!
How to: Reduce Graphics Flicker with Double Buffering for Forms and Controls:
http://msdn.microsoft.com/en-us/libr...v=vs.110).aspx
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Feb 9th, 2014, 02:48 PM
#3
Thread Starter
New Member
Re: Drawing gdi+ flickering??? Heeeelp!
Thanks for the reply, i have tried it out before but i coulnt see any difference, maybe because i was using Me.CreateGraphics.
Do you have any clue why when i pass the e.Graphics.Drawline(_pen, _StartPoint, _EndPoint) to OnPaint it doesnt refresh anything? I used to call it via Me.Invalidate, Me.Refresh, Me.Update but the OnPaint doesnt reflect the code given?
Anyone help!
-
Feb 9th, 2014, 04:45 PM
#4
Re: Drawing gdi+ flickering??? Heeeelp!
CreateGraphics causes all kinds of trouble when used for drawing. Your OnPaint sub won't have any effect if you have left out MyBase.OnPaint. I suggest you transfer all the code except Invalidate from [Refresh] to OnPaint, replacing Me.CreateGraphics by e.Graphics. Unless you need it for some other reason, you could then get rid of the shadowed Refresh sub altogether and put Me.Invalidate in the property Set clause.
To prevent flickering, put Me.DoubleBuffered = True in the UserControl's New sub.
BB
-
Feb 10th, 2014, 03:00 PM
#5
Thread Starter
New Member
Re: Control flickers when Drawing multiple elements in short times!
Thanks boops boops, that helped. Also there was an error in my code which i realised later. Putting MyBase.OnPaint(e) at the end of OnPaint() clause was not necessary.
Here is the solution for other people having flickering Controls, i also have found a manual way to buffer the drawings on Web, but setting Me.DoubleBuffered = True would be less code;
Code:
Class TEST
Inherits Form ' or Inherits UserControl whatever!
Private _doBuffer As Boolean = False ' We will use the automated solution Me.DoubleBuffered = True, otherwise Me.DoubleBuffered = False if using "_doBuffer"
Private _backBuffer As Bitmap
Sub New
Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.DoubleBuffer, True)
End Sub
'CALL THIS SUB WHENEVER YOU WANT TO PAINT THE STUFF ON "OnPaint()"
PUBLIC SUB Paint_MyStuff
Invalidate
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
If _backBuffer Is Nothing Then
_backBuffer = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)
End If
Dim g As Graphics = Nothing
If _doBuffer Then
g = Graphics.FromImage(_backBuffer)
Else
g = e.Graphics
End If
g.Clear(Me.BackColor)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'STUFF TO DRAW ON CONTROL;
For i As Integer = 0 To Me.Height Step +1
g.DrawLine(New Pen(Brushes.Blue, 1.0F), New Point(0,0), New Point(Me.Width, i))
Next
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If _doBuffer Then
g.Dispose()
'Copy the back buffer to the screen
e.Graphics.DrawImageUnscaled(_backBuffer, 0, 0)
End If
MyBase.OnPaint(e) '//optional but not recommended
End Sub 'OnPaint
Protected Overrides Sub OnPaintBackground(ByVal pevent As PaintEventArgs)
'Do stuff (OPTIONAL)
End Sub 'OnPaintBackground
'Don't allow the background to paint
Protected Overrides Sub OnSizeChanged(ByVal e As EventArgs)
Me.CreateGraphics.Clear(Me.BackColor)
If Not (_backBuffer Is Nothing) Then
_backBuffer.Dispose()
_backBuffer = Nothing
End If
MyBase.OnSizeChanged(e)
End Sub 'OnSizeChanged
End Class
Last edited by Begi; Feb 10th, 2014 at 03:05 PM.
-
Feb 10th, 2014, 03:06 PM
#6
Re: Drawing gdi+ flickering??? Heeeelp!
By the way, you shouldn't be messing with thread prioritization unless you have a REALLY good reason. Increasing the priority of a thread doesn't mean that it gets more time, it means that it gets ALL the time. Lower priority threads only get to use the CPU if there are no higher priority threads pending. In theory, boosting your app to the highest thread priority would mean that it would be at the same level as the OS noticing keypresses, and so on. That can ruin system performance and behavior because your app is dependent on getting keyboard events from the OS, but it might block the OS from even noticing keys being pressed. In practice, the impact will not be THAT bad, but it could still be pretty horrible.
My usual boring signature: Nothing
 
-
Feb 10th, 2014, 03:09 PM
#7
Thread Starter
New Member
Re: Drawing gdi+ flickering??? Heeeelp!
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|