Panel flicker

G

Guest

I migrated a VB6.0 application to VB.NET. This app has a drawing area, which
is a panel. The user can drag and drop several objects on this drawing area
and can also draw lines, boxes etc. The app is sufferring from the problem of
flicker.

On reading several posts on this forum and others I decided to enable double
buffering for my panel. However the drawing area appears blank. I can briefly
see the objects when adding new objects on the drawing area.

I have a context menu associated w/ the panel. On clicking the Show option
in the context menu, the drawing appears, however on resizing the form or
adding a new object to the drawing area, the screen becomes blank again.

Any idea as to what I am missing here?

Posting some code snippets below, if that will help.

Thanks in advance for your help.


Code:

'This class defines an object which is a specialized panel, which eliminates
'the flickering effect when used as a drawing pad

Public Class CBufferedPanel
Inherits Panel

Public Sub New()
MyBase.New()

SetStyle(ControlStyles.AllPaintingInWmPaint Or _
ControlStyles.DoubleBuffer Or _
ControlStyles.ResizeRedraw Or _
ControlStyles.UserPaint, _
True)

UpdateStyles()
End Sub
End Class

'In the form that has the panel, I define picSegment of type CBuffered class
and instantiate it
Public Class DrawingArea
Inherits System.Windows.Forms.Form

Private Sub picSegment_Paint(ByVal Sender As Object, ByVal pea As
PaintEventArgs) _
Handles picSegment.Paint

'Paint method calls the draw routine
DrawAll(picSegment, True)
End Sub

End Class
 
K

Ken Tucker [MVP]

Hi,

You need to use the graphics object passed to you in paint event to
draw on the panel. I dont see you passing it to your drawall procedure.
The graphics object is passed in pea.

Ken
 
G

Guest

Hi Ken,

Thanks for your response. I pass the panel "picSegment" to the DrawAll
method and create a graphics object in the DrawAll method. The various
objects on the screen are drawn by their individual methods.

I am pasting the code snippet for your ref.

Thanks in advance for your help.

///
Public Sub DrawAll(ByVal Pic As Object, Optional ByVal Clear As
Boolean = True, _
Optional ByVal watermark As Boolean = False)

Dim wm As String
Dim g As Graphics

g = Pic.CreateGraphics

If Clear Then g.Clear(Pic.BackColor)

If watermark = True Then
wm = "Copyright "
Pic.Font = New Font("Arial", 28)

CurrentX = (Pic.ClientRectangle.Width - g.MeasureString(wm,
Pic.Font).Width) / 2
CurrentY = (Pic.ClientRectangle.Height - g.MeasureString(wm,
Pic.Font).Height) / 2
g.DrawString(wm, Pic.Font, WmarkBrush, CurrentX, CurrentY)

Pic.Font = New Font("Arial", 8)
End If

For Each child In Items
child.Paint(Pic)
Next child

For Each child In Links
child.Paint(Pic)
Next child

For Each child In Texts
child.Paint(Pic)
Next child

For Each child In Lines
child.Paint(Pic)
Next child

For Each child In Boxes
child.Paint(Pic)
Next child

g.Dispose()
WmarkBrush.Dispose()
End Sub
\\\
 
R

Ronchese

You are calling your DrawAll method in the OnPaint() event already?

A suggestion to improve your painting is write the image in a new bitmap,
and later draw it directly to control's graphic object.

For sample:



Private Sub MyGrid_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

Dim g As System.Drawing.Graphics

(...)

Dim bmp As New Bitmap(rectClient.Width, rectClient.Height,
Imaging.PixelFormat.Format32bppArgb)
g = Graphics.FromImage(bmp)

(...) 'draw everything in the g object created above

'transfer to control's graphics object
e.Graphics.DrawImage(bmp, New Point(0, 0))

'release memory
g.Dispose()

End sub



[]s
Cesar



"Sarika" <[email protected]> escreveu na mensagem
Hi Ken,

Thanks for your response. I pass the panel "picSegment" to the DrawAll
method and create a graphics object in the DrawAll method. The various
objects on the screen are drawn by their individual methods.

I am pasting the code snippet for your ref.

Thanks in advance for your help.

///
Public Sub DrawAll(ByVal Pic As Object, Optional ByVal Clear As
Boolean = True, _
Optional ByVal watermark As Boolean = False)

Dim wm As String
Dim g As Graphics

g = Pic.CreateGraphics

If Clear Then g.Clear(Pic.BackColor)

If watermark = True Then
wm = "Copyright "
Pic.Font = New Font("Arial", 28)

CurrentX = (Pic.ClientRectangle.Width - g.MeasureString(wm,
Pic.Font).Width) / 2
CurrentY = (Pic.ClientRectangle.Height - g.MeasureString(wm,
Pic.Font).Height) / 2
g.DrawString(wm, Pic.Font, WmarkBrush, CurrentX, CurrentY)

Pic.Font = New Font("Arial", 8)
End If

For Each child In Items
child.Paint(Pic)
Next child

For Each child In Links
child.Paint(Pic)
Next child

For Each child In Texts
child.Paint(Pic)
Next child

For Each child In Lines
child.Paint(Pic)
Next child

For Each child In Boxes
child.Paint(Pic)
Next child

g.Dispose()
WmarkBrush.Dispose()
End Sub
\\\
 
G

Guest

Thanks all for your inputs.

As mentioned in <a href="http://www.bobpowell.net/creategraphics.htm">GDI
Info</a> and also by you, I improvised my Paint routine. I was unnecessarily
creating a Graphics object instead of utilizing the object provided by the
PaintEventArgs argument. After optimizing the routine I enabled double
buffering on the Panel and yohoo! the flicker was gone...

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top