[英]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
。 這將重繪一個區域並縮短繪圖時間。 您也可以通過一個srcRect
到Graphics.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.