我正在尝试为我的应用程序创建一个简单的图表,显示每100毫秒的实时数据。所以我想我可以使用DrawCurve
方法绘制图形线,并从以下代码开始:
class BufferedPanel : Panel
{
public BufferedPanel()
{
this.DoubleBuffered = true; //to avoid flickering of the panel
}
}
class Form2: Form
{
BufferedPanel panel1 = new BufferedPanel();
List<Point> graphPoints = new List<System.Drawing.Point>();
private void Form2_Load(object sender, EventArgs e)
{
this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = e.Graphics)
{
Point[] points = graphPoints.ToArray();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
if (points.Length > 1)
g.DrawCurve(graphPen, points);
}
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
graphPoints.Add(new System.Drawing.Point(counter * steps, (int)(float)e.UserState)); //x - regular interval decided by a constant; y - simulated by background worker
panel1.Refresh();
counter++;
}
}
截至目前,我正在从后台工作线程模拟graphPoints的值。我的问题是,当我对我的面板进行双重缓冲时,我无法看到图形线。当我将doublebuffering设置为false时,它运行良好。我是使用Graphics
进行绘图的新手。所以我不太清楚它是如何工作的。请帮助我。
此外,当图表线到达面板末尾时,我希望实现AutoScrolling
。你能就这个方法提出一个想法吗?
这是我工作图的图像:
答案 0 :(得分:2)
using (Graphics g = e.Graphics)
那很糟糕。这会破坏传递给Paint事件处理程序的Graphics对象。当你的事件处理程序返回时,没有什么可以用这个对象完成,它是一个死鹦鹉。所以不要指望之后有什么工作,包括打开双缓冲时需要发生的事情,需要将缓冲区绘制到屏幕上才能看到。
使用使用语句或Dispose()方法有一个简单的规则。如果你创建了一个对象,那么你就拥有了它,你可以将其销毁。放手,你没有创造它。
有些证据表明你的“graphPen”变量也出错了。笔绝对是您在Paint事件处理程序中创建和销毁的对象。不要存储一个只是不必要地占用GDI堆中的空间,不值得创建一个所需的几微秒。你肯定会使用笔的使用语句。
所以快速解决方法是:
var g = e.Graphics;