1

我正在尝试为我的应用程序制作一个简单的图表,该图表显示每 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 的值。我的问题是,当我对面板进行双重缓冲时,我无法看到图形线。当我将双缓冲设置为 false 时效果很好。我不熟悉使用Graphics. 所以我不太确定它是如何工作的。请帮助我。

另外,我想AutoScrolling在图形线到达面板末端时实现。你能提出一个关于如何做的想法吗?

这是我的工作图的图像:

在此处输入图像描述

4

1 回答 1

2
    using (Graphics g = e.Graphics)

那很糟。这会破坏传递给 Paint 事件处理程序的 Graphics 对象。当您的事件处理程序返回时,对该对象无能为力,它是一只死鹦鹉。因此,不要指望之后有任何工作,包括打开双缓冲时需要发生的事情,需要将缓冲区绘制到屏幕上才能看到。

正确使用using语句或 Dispose() 方法有一个简单的规则。如果您创建了一个对象,那么您就拥有它,并且您可以销毁它。放下它,你没有创造它。

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

所以快速修复是:

    var g = e.Graphics;
于 2012-12-15T12:08:07.503 回答