Graphics rendering to a Panel is immediately cleared ???

  • Thread starter Thread starter Paul_Madden
  • Start date Start date
P

Paul_Madden

I have a System.Windows.Forms.Form onto which I add a Panel (MyPanel)
directly derived from System.Windows.Forms.Panel.

Here are the important code fragments ...

public class MyPanel : Panel
{
.............................

public MyPanel () : base ()
{
this.SetStyle (ControlStyles.DoubleBuffer, true);
this.SetStyle (ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle (ControlStyles.UserPaint, true);
}

protected override void OnPaintBackground (PaintEventArgs pe)
{
return;
}

protected override void OnPaint (PaintEventArgs pe)
{
using (Graphics g = this.CreateGraphics ())

.............
..........................................

The "OnPaint ()" routine uses the graphics context to draw some graphs etc.

Now, I have added the override to "OnPaintBackground ()" in order to see the
order of events which take place. In reality I do NOT override this method as
the standard Panel implementation does all I need it to do.

What happens is OnPaintBackground is entered and when exited On Paint is
entered.. So far so good.

When I simply let the app fly, every second I call Refresh () on the single
instance of the MyPanel object, this in turn ultimately invokes my On Paint
method which redraws my graphs. HOWEVER, the graph appears very quickly, then
is cleared again and the standard Form grey background replaces the graph
drawn in the panel.

Why is my Panel data displayed correctly but then instantly cleared. I send
the Refresh call directly to the MyPanel instance and not to the parent form.

I have moved the code logic from a combination that ALMOST worked perfectly,
ie the double buffering worked but wanted to remove the initial erase flicker.
In this previous working scneario, I had a Panel (not a derived Panel, ie
MyPanel), which sat directly on a CustomControl. Then the Refresh () produced
the graph data that persisted on the display until the second timer fired and
the data (plus flicker) was then redisplayed. WHY BY USING MY DERIVED PANEL
ON A FORM DOES MY CODE BEHAVE SO DIFFERENTLY TO THAT OF DISPLAYING A NATICE
PANEL ON A CUSTOMCONTROL.

So, once again, my graph appears for an instant, then is overwritten by the
standard Form Grey background colour. I do NOT have an active
OnPaintBackground and do NOT handle the associated event.

Many thanks for your time.
 
Since you don't handle the OnPaintBackground, perhaps the base class
event is firing and that is what is erasing your background? Perhaps
you should handle the OnPaintBackground and then NOT call the base
class handler.

Also, you might check the Control.SetStyle command and use the
AllPaintingInWmPaint enum. I think that prevents the background from
being erased.

One last thought, does you OnPaint call the base class OnPaint? Where
does this happen?
 
Whoops! I re-read your post and that you are calling SetStyle so
ignore that part of my reply.
 
The OnPaint method passes the Graphics instnace to your app via the
PaintEventArgs. You're not using it.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Numbskull

Hard work is a medication for which
there is no placebo.
 
Hoi Kevin. You are indeed correct. I am in the UK now and will return to my
office in Zeurich late Monday . I will try using the graphics context passed
via "pe". I was assuming te "this.CreateGraphics" would point to one and the
same.

This is the first time I have used this forum and am absolutely astonished at
just how many threads are started each day. Shame the rest of the world can't
colaborate so eagerly in all matters political.

I'll let you know how things pan out when I give it a go.

Many thanks Kevin.

Paul.

Kevin said:
The OnPaint method passes the Graphics instnace to your app via the
PaintEventArgs. You're not using it.
I have a System.Windows.Forms.Form onto which I add a Panel (MyPanel)
directly derived from System.Windows.Forms.Panel.
[quoted text clipped - 71 lines]
Many thanks for your time.
 
What I have noticed is that when I do not override, the base class
OnPaintBackground fires, followed by my OnPaint routine. Things are fine up
to here. However, after the OnPaint call, the background is again cleared.
The call stack which results from my original call to myPanel.Refresh () is
pretty deep and I believe something is happening as I travers back up the
stack, after my OnPaint () routine has been called.
 
Hoi Kevin, many many thanks. This was indeed the problem. I assumed the
Graphics context returned by this.CreateGraphics would be OK. Don't
understand why pe.Graphics passed to the Paint routine differs but it sure
does.

Now have flicker free graphics which persist.

Many many thanks once again.

Paul.


Kevin said:
The OnPaint method passes the Graphics instnace to your app via the
PaintEventArgs. You're not using it.
I have a System.Windows.Forms.Form onto which I add a Panel (MyPanel)
directly derived from System.Windows.Forms.Panel.
[quoted text clipped - 71 lines]
Many thanks for your time.
 
Back
Top