Redrawing only part of a panel control

P

Peter Webb

I'm well advanced into a card game which uses the cards.dll library from
Solitaire to display cards. You give it a graphic surface and tell it where
to paint what, works just fine.

I have always noticed a bit of flicker when moving a card and hence
repainting all 52 cards on the panel; no problem, I thought, just redraw
only the card stacks that have changed. I'm at that point now.

My playing card surface is a panel. The cards.dll is not neccesary to show
my problem.

The following code snippet illustrates my solution, which does not work. I
toggle a variable in On_Paint which says whether to do a base.OnPaint and
redraw everything, or just overwrite an area of the screen with the
background color and draw what I need.

If my variable redrawOnlySecondRectangle is false, it does on base.OnPaint,
draws a rectangle top left, then overwrites a second area of the screen with
the backgroundcolor, then draws a smaller rectangle in this area.

That works fine.

If redrawOnlySecondRectangle is true, it should and does skip the
base.onPaint, which means I don't have to redraw the first rectangle, and it
just draws the second rectangle.

I then always set redrawOnlySecondRectangle to false to handle "normal"
paint events.

When I run this, and toggle the variable and force a redraw, if its set to
redraw only the second rectangle then I only see the second rectangle. The
first rectangle is no longer there.

Its as if it *always* forces a base.OnPaint, which it doesn't.

Hiding the window and the revealing it shows two rectangles, ie it does a
full redraw as it should.

I have re-written all of the above from my cards program, which
mis-functions in exactly the same way.

Any ideas?


static bool redrawOnlySecondRectangle = false;

public class TestPanel : Panel
{
protected override void OnPaint(PaintEventArgs e)
{ System.Drawing.Graphics panelGraphics = e.Graphics;
System.Drawing.SolidBrush brush1 =
new
System.Drawing.SolidBrush(System.Drawing.Color.Blue);

if (!redrawOnlySecondRectangle)
{
base.OnPaint(e); // only repaint background if doing a
full refresh

panelGraphics.FillRectangle(brush1, new
System.Drawing.Rectangle(0, 0, 100, 100));
}

// overwrite part of panel with background color

System.Drawing.SolidBrush backgroundColorBrush =
new System.Drawing.SolidBrush(this.BackColor);
panelGraphics.FillRectangle(brush1, new
System.Drawing.Rectangle(100, 100, 50, 50));

// draw the second rectangle

System.Drawing.SolidBrush brush2 =
new
System.Drawing.SolidBrush(System.Drawing.Color.Yellow);

panelGraphics.FillRectangle(brush2, new
System.Drawing.Rectangle(120, 120, 10, 10));

brush1.Dispose();
brush2.Dispose();
backgroundColorBrush.Dispose();
panelGraphics.Dispose();

redrawOnlySecondRectangle = false;

}
};
 
J

James Parker

I'm well advanced into a card game which uses the cards.dll library from
Solitaire to display cards. You give it a graphic surface and tell it where
to paint what, works just fine.

I have always noticed a bit of flicker when moving a card and hence
repainting all 52 cards on the panel; no problem, I thought, just redraw
only the card stacks that have changed. I'm at that point now.

My playing card surface is a panel. The cards.dll is not neccesary to show
my problem.

The following code snippet illustrates my solution, which does not work. I
toggle a variable in On_Paint which says whether to do a base.OnPaint and
redraw everything, or just overwrite an area of the screen with the
background color and draw what I need.

If my variable redrawOnlySecondRectangle is false, it does on base.OnPaint,
draws a rectangle top left, then overwrites a second area of the screen with
the backgroundcolor, then draws a smaller rectangle in this area.

That works fine.

If redrawOnlySecondRectangle is true, it should and does skip the
base.onPaint, which means I don't have to redraw the first rectangle, and it
just draws the second rectangle.

I then always set redrawOnlySecondRectangle to false to handle "normal"
paint events.

When I run this, and toggle the variable and force a redraw, if its set to
redraw only the second rectangle then I only see the second rectangle. The
first rectangle is no longer there.

Its as if it *always* forces a base.OnPaint, which it doesn't.

Hiding the window and the revealing it shows two rectangles, ie it does a
full redraw as it should.

I have re-written all of the above from my cards program, which
mis-functions in exactly the same way.

Any ideas?


static bool redrawOnlySecondRectangle = false;

public class TestPanel : Panel
{
protected override void OnPaint(PaintEventArgs e)
{ System.Drawing.Graphics panelGraphics = e.Graphics;
System.Drawing.SolidBrush brush1 =
new
System.Drawing.SolidBrush(System.Drawing.Color.Blue);

if (!redrawOnlySecondRectangle)
{
base.OnPaint(e); // only repaint background if doing a
full refresh

panelGraphics.FillRectangle(brush1, new
System.Drawing.Rectangle(0, 0, 100, 100));
}

// overwrite part of panel with background color

System.Drawing.SolidBrush backgroundColorBrush =
new System.Drawing.SolidBrush(this.BackColor);
panelGraphics.FillRectangle(brush1, new
System.Drawing.Rectangle(100, 100, 50, 50));

// draw the second rectangle

System.Drawing.SolidBrush brush2 =
new
System.Drawing.SolidBrush(System.Drawing.Color.Yellow);

panelGraphics.FillRectangle(brush2, new
System.Drawing.Rectangle(120, 120, 10, 10));

brush1.Dispose();
brush2.Dispose();
backgroundColorBrush.Dispose();
panelGraphics.Dispose();

redrawOnlySecondRectangle = false;

}
};

Have you tried setting the windows form Double Buffering property to true.

http://msdn.microsoft.com/en-us/library/3t7htc9c.aspx

Hope this helps

j1mb0jay
 

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