[英]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.