简体   繁体   English

在绘制循环C#winforms上无效

[英]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 我想在绘制之前删除以前的更改,但是如果我使用Invalidate()或Refresh(),它将永远重绘它(闪烁),奇怪的是,我在任何绘制之前都调用Invalidate(),所以如果强制面板油漆,我看不到图纸

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. 无论如何,事实证明我从来不需要它,即使没有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. 当我不久前创建的程序调用Invalidate时,我的控件闪烁出现问题。 I found overriding the OnPaintBackGround did the trick, it may work for you too; 我发现重写OnPaintBackGround可以解决问题,它可能也对您有用;

    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! 不要画离屏位图中OnPaint事件,但每当要绘制的内容的变化!

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. 另外,按照OnPaintBackground建议重写OnPaintBackground方法,以防止控件在绘制自身之前清除背景。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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