在PictureBox上绘图

时间:2012-07-18 10:15:56

标签: c# winforms drawing picturebox

UserControl我有PictureBox和其他一些控件。对于包含名为Graph的此图片框的用户控件,我有一种在此图片框上绘制曲线的方法:

    //Method to draw X and Y axis on the graph
    private bool DrawAxis(PaintEventArgs e)
    {
        var g = e.Graphics;
        g.DrawLine(_penAxisMain, (float)(Graph.Bounds.Width / 2), 0, (float)(Graph.Bounds.Width / 2), (float)Bounds.Height);
        g.DrawLine(_penAxisMain, 0, (float)(Graph.Bounds.Height / 2), Graph.Bounds.Width, (float)(Graph.Bounds.Height / 2));

        return true;
    }

    //Painting the Graph
    private void Graph_Paint(object sender, PaintEventArgs e)
    {
        base.OnPaint(e);
        DrawAxis(e);
     }

    //Public method to draw curve on picturebox
    public void DrawData(PointF[] points)
    {
        var bmp = Graph.Image;
        var g = Graphics.FromImage(bmp);

        g.DrawCurve(_penAxisMain, points);

        Graph.Image = bmp;
        g.Dispose();
    }

应用程序启动时,将绘制轴。但是当我调用DrawData方法时,我得到的异常是bmp为空。可能是什么问题?

我还希望能够多次调用DrawData以在用户点击某些按钮时显示多条曲线。实现这个目标的最佳途径是什么?

谢谢

1 个答案:

答案 0 :(得分:5)

您从未分配过Image,对吗?如果你想在PictureBox'图像上绘图,首先需要创建这个图像,方法是为它指定一个带有PictureBox尺寸的位图:

Graph.Image = new System.Drawing.Bitmap(Graph.Width, Graph.Height);

你只需要一次,如果你想在那里重新绘制任何内容,那么可以重复使用该图像。

然后,您可以随后使用此图像进行绘图。有关详细信息,请refer to the documentation

顺便说一下,这完全独立于绘制PictureBox事件处理程序中的Paint。后者直接使用控件,而Image作为后备缓冲区自动绘制在控件上(但需要调用Invalidate来触发重绘,在后备缓冲区上绘图后。)

此外,绘制后将位图重新分配给PictureBox.Image属性会使 no 有意义。这项行动毫无意义。

还有别的,因为Graphics对象是一次性的,你应该将它放在using块中,而不是手动处理它。这可以保证在例外情况下正确处置:

public void DrawData(PointF[] points)
{
    var bmp = Graph.Image;
    using(var g = Graphics.FromImage(bmp)) {
        // Probably necessary for you:
        g.Clear();
        g.DrawCurve(_penAxisMain, points);
    }

    Graph.Invalidate(); // Trigger redraw of the control.
}

您应该将此视为固定模式。