2012-12-15 56 views
1

我想为我的应用程序制作一个简单的图形,其中显示每100毫秒的实时数据。所以,我想我可以使用DrawCurve方法来绘制图线,并开始与下面的代码:在Winforms中创建自定义图形

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。你能提出一个关于如何去做的想法吗?

这是我的工作图的图像:

enter image description here

回答

2
using (Graphics g = e.Graphics) 

这是不好的。这会破坏传递给Paint事件处理程序的Graphics对象。当你的事件处理程序返回时,对象没有任何东西可以做,它就是一只死去的鹦鹉。因此,不要期望事后有任何工作,包括开启双缓冲时需要发生的事情,需要将缓冲区绘制到屏幕上以便可见。

有一个简单的规则,使用正确使用语句或Dispose()方法。如果你创建了一个对象,那么你拥有它,它是你的摧毁它。把它关掉,你没有创建它。

一些证据表明,你也得到了“graphPen”变量的错误。钢笔绝对是您在Paint事件处理程序中创建和销毁的对象。不要存储一个,只是不必要地占用GDI堆中的空间,这不值得创建一个微秒。您肯定会使用使用语句作为笔。

所以速战速决是:

var g = e.Graphics; 
+0

感谢您更正错误。它现在运行良好。你能帮我实施面板的自动滚动吗? – sarath

+1

当然,请点击提问按钮来解释您的问题。 –

+0

这是这个问题的一部分。无论如何,我会深入挖掘它。谢谢 :) – sarath