簡體   English   中英

C#繪圖程序閃爍

[英]C# paint program flickering

我正在嘗試用C#制作一個簡單的繪圖程序,但是當我繪圖時它會一直閃爍,就像我需要某種雙緩沖一樣,但我不知道該怎么做。

我正在繪制一個Panel ,我正在使用Bitmap來存儲圖形。

這是我的代碼:

public partial class Form1 : Form
{
    private Bitmap drawing;
    private bool leftDown = false;
    private int prevX;
    private int prevY;
    private int currentX;
    private int currentY;

    public Form1()
    {
        InitializeComponent();

        drawing = new Bitmap(panel1.Width, panel1.Height);
    }

    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            leftDown = true;

            prevX = e.X;
            prevY = e.Y;
        }
    }

    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
        if (leftDown)
        {
            Graphics g = Graphics.FromImage(drawing);

            currentX = e.X;
            currentY = e.Y;

            g.DrawLine(new Pen(Color.Black), new Point(currentX, currentY), new Point(prevX, prevY));
            panel1.Invalidate();

            prevX = currentX;
            prevY = currentY;

            g.Dispose();
        }
    }

    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        leftDown = false;
    }

    private void panel1_MouseLeave(object sender, EventArgs e)
    {
        leftDown = false;
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawImageUnscaled(drawing, 0, 0);
    }
}

您不僅應該將DoubleBuffered轉為true ,還要使用PictureBox而不是Panel並在其上繪制。 這應該解決你的問題:)。

您需要子類化Panel才能執行此操作,因為您需要覆蓋某些內容。 像這樣的Panel應該工作:

class DoubleBufferedPanel : Panel {
    public DoubleBufferedPanel() : base() {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.DoubleBuffered |
                      ControlStyles.Opaque |
                      ControlStyles.OptimizedDoubleBuffer, true);
    }
    public override void OnPaint(PaintEventArgs e) {
        // Do your painting *here* instead, and don't call the base method.
    }

    // Override OnMouseMove, etc. here as well.
}

但是,您根本不需要Panel添加到Control的功能,即它可以作為容器運行。 所以,事實上,除非你需要子Control否則你應該從Control繼承。

另一個改進可能是僅對已更改的Rectangle進行Invalidate 這將重繪一個區域並縮短繪圖時間。 您也可以通過一個srcRectGraphics.DrawImage ,即srcRect是從計算e.ClipRectangle ,甚至更好的性能,如果子類Panel不會為你工作。

通常,只需添加this.DoubleBuffered = true; 在你的代碼中應該做的伎倆。

如果沒有,請將此代碼添加到表單中:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

您也可以使用Reflection更改它,但沒有優勢,無論是可讀性還是速度。

在Paint事件中繪制像素貼圖時,閃爍通常是由Windows窗體引起的,因為它首先繪制背景,然后繪制像素貼圖。 因此,閃爍是在幾分之一秒內變得可見的背景。

您可以在面板的ControlStyle屬性中設置Opaque樣式。 這將轉變背景圖,因為Windows窗體現在假定您的代碼將完全繪制面板的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM