Paint event of a panel

A

Aaron Smith

I have a panel that I have in the paint event to draw a Raised 3d border
around it.. The problem is, if a msgbox is popped up or a tooltip is
displayed, it leaves lines on the panel. I've tried invalidate after the
msgbox to no avail...

Here is the event:
Private Sub Panel2_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Panel2.Paint
ControlPaint.DrawBorder3D(e.Graphics, e.ClipRectangle,
Border3DStyle.Raised)
End Sub

I've tried calling the base event too, which seemed to do nothing..

Thanks,
Aaron
 
B

Bob Powell [MVP]

Firstly, don't draw borders in the paint event. Add a border to the object
using the window properties or handle the non-client messages correctly.
Windows Forms Tips and Tricks has information on the first option.

Secondly, ControlPaint is a total cheat because it often draws on the deskop
window, not the control window. This is why it leaves unwanted traces of
itself and why you should draw your borders correctly.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
A

Aaron Smith

Bob,

The example that I found on your site is all well and good, but what
about raised 3d borders? I do not want the sunken 3d panel, I want a
raised one. Will it work the same way if I sublcass the panel and set it
through the CreateParams? Again, I'm not doing this in a custom control,
I'm doing it in the standard windows forms panel.

Aaron
 
J

Jay B. Harlow [MVP - Outlook]

Aaron,
e.ClipRectangle represents the part of the Panel that needs to be repainted,
it is not the entire panel.

If you want a border around the entire Panel use Panel.ClientRectangle
instead.

Something like:
Private Sub Panel2_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Panel2.Paint
ControlPaint.DrawBorder3D(e.Graphics, Panel2.ClientRectangle,
Border3DStyle.Raised)
End Sub

You should also consider setting the Panel.DisplayRectangle to compensate
for the size of the border. As DisplayRectangle represents the amount of
usable space in the control that is not used for "adornments" such as the
border. Returning DisplayRectangle is important if you have controls within
your Panel that rely on Docking & Anchoring as Docking & Anchoring take
DisplayRectangle into account...

Note to set the DisplayRectangle you actually have to override the property
in a derived class, which I would do to encapsulate the painting any way.
Something like:

Public Class PanelEx
Inherits System.Windows.Forms.Panel

Public Overrides ReadOnly Property DisplayRectangle() As
System.Drawing.Rectangle
Get
Dim value As Rectangle = ClientRectangle
Dim size As size = SystemInformation.Border3DSize
value.Inflate(size.Width * -1, size.Height * -1)
Return value
End Get
End Property

Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle,
Border3DStyle.Raised)
End Sub

End Class

Then every place you want a panel with a 3D border you would use a PanelEx
instead of the normal Panel.

Hope this helps
Jay
 
A

Aaron Smith

Jay,

You rock. That was it. I sat here and played with it more after Bob's
reply thinking it shouldn't have to be that difficult to do what I want.
I saw that if I minimized the window and then restored it, it fixed it.
So I've been trying to find that property... I'm glad you responded. I
probably would have not found it for a long time. lol

Thanks Again,
Aaron
Aaron,
e.ClipRectangle represents the part of the Panel that needs to be repainted,
it is not the entire panel.

If you want a border around the entire Panel use Panel.ClientRectangle
instead.

Something like:

Private Sub Panel2_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Panel2.Paint
ControlPaint.DrawBorder3D(e.Graphics, Panel2.ClientRectangle,
Border3DStyle.Raised)
End Sub


You should also consider setting the Panel.DisplayRectangle to compensate
for the size of the border. As DisplayRectangle represents the amount of
usable space in the control that is not used for "adornments" such as the
border. Returning DisplayRectangle is important if you have controls within
your Panel that rely on Docking & Anchoring as Docking & Anchoring take
DisplayRectangle into account...

Note to set the DisplayRectangle you actually have to override the property
in a derived class, which I would do to encapsulate the painting any way.
Something like:

Public Class PanelEx
Inherits System.Windows.Forms.Panel

Public Overrides ReadOnly Property DisplayRectangle() As
System.Drawing.Rectangle
Get
Dim value As Rectangle = ClientRectangle
Dim size As size = SystemInformation.Border3DSize
value.Inflate(size.Width * -1, size.Height * -1)
Return value
End Get
End Property

Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle,
Border3DStyle.Raised)
End Sub

End Class

Then every place you want a panel with a 3D border you would use a PanelEx
instead of the normal Panel.

Hope this helps
Jay
 

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