简体   繁体   中英

Invalidate on paint loops C# winforms

I have a panel I draw on, and I'm doing it in the paint event. I want to delete previous changes before drawing, but If I use Invalidate() or Refresh() it is redrawing it forever (it is flickering), and the strange thing is I call Invalidate() before any drawing, so if it's just forcing panel paint I shouldn't see the drawing

Edit: I figured out this:

        void _paint(object sender, PaintEventArgs e)
    {
        Panel P = (Panel)sender;
        if (painted = false) { painted = true; P.Invalidate(); }


        Shows(30);
        painted = false;
    }

It stopped flickering. Anyway, turns out I've never needed that, it is repainting the panel even without the Invalidation. But strangely when I hide only part of the panel(either with form resizing or dragging window over the panel),when becoming visible again it is painted, not repainted(I can tell because the anti-aliasing becomes solid color, producing shitty result), that's why I thought I need to Invalidate the panel. Invalidating won't stop it from happening. I think probably another event is triggered, not paint.

I encountered a problem with my control flickering when I called Invalidate with a program I created not too long ago. I found overriding the OnPaintBackGround did the trick, it may work for you too;

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        /* Override to stop the background being repainted -> this stops flashing of the text */
    }

First if all, the following condition is lacking an = sign:

if (painted = false) { painted = true; P.Invalidate(); }

It should read

if (painted == false) { painted = true; P.Invalidate(); }

or

if (!painted) { painted = true; P.Invalidate(); }

Secondly, double buffering is in many cases a good idea. To do so, paint all the content into an off-screen bitmap that has the same size as the client area of your control and then draw that bitmap to the target control if needed. Do not draw the off-screen bitmap in the OnPaint event, but whenever the content to be drawn changes!

Example:

private void PaintOffscreen()
{
    // Do whatever necessary to draw the offscreen bitmap
    ...

    // Cause the control to repaint itself. Change OnPaint to draw the bitmap only
    Invalidate();
}

void _paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(offscreenBitmap, 0, 0);
}

Also, override the OnPaintBackground method as suggested by HorHAY to prevent the control from clearing the background before painting itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM