C# 在PictureBox上绘图

C# 在PictureBox上绘图,c#,winforms,drawing,picturebox,C#,Winforms,Drawing,Picturebox,在UserControl中,我有一个PictureBox和一些其他控件。对于包含名为Graph的picturebox的用户控件,我有一种在该图片框上绘制曲线的方法: //Method to draw X and Y axis on the graph private bool DrawAxis(PaintEventArgs e) { var g = e.Graphics; g.DrawLine(_penAxisMain, (float)(G

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

    //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为null。有什么问题吗

我还希望能够多次调用DrawData,在用户单击某些按钮时显示多条曲线。实现这一目标的最佳方式是什么

谢谢

您从未分配过图像,对吗?如果要在PictureBox的图像上绘制,需要首先创建此图像,方法是为其指定一个具有PictureBox尺寸的位图:

Graph.Image = new System.Drawing.Bitmap(Graph.Width, Graph.Height);
你只需要做一次,如果你想重画上面的任何东西,图像就可以被重用

然后,可以随后使用此图像进行绘制。有关详细信息

顺便说一下,这完全独立于在Paint事件处理程序中的PictureBox上绘制。后者直接在控件上绘制,而图像用作backbuffer,它自动绘制在控件上,但在backbuffer上绘制后,确实需要调用Invalidate来触发重画

此外,在绘制后将位图重新指定给PictureBox.Image属性是没有意义的。手术毫无意义

另外,由于图形对象是一次性的,您应该将其放在使用块中,而不是手动处理。这保证了在异常情况下的正确处理:

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.
}
<>你应该认为这是固定的模式。

你从来没有指定过图像,对吧?如果要在PictureBox的图像上绘制,需要首先创建此图像,方法是为其指定一个具有PictureBox尺寸的位图:

Graph.Image = new System.Drawing.Bitmap(Graph.Width, Graph.Height);
你只需要做一次,如果你想重画上面的任何东西,图像就可以被重用

然后,可以随后使用此图像进行绘制。有关详细信息

顺便说一下,这完全独立于在Paint事件处理程序中的PictureBox上绘制。后者直接在控件上绘制,而图像用作backbuffer,它自动绘制在控件上,但在backbuffer上绘制后,确实需要调用Invalidate来触发重画

此外,在绘制后将位图重新指定给PictureBox.Image属性是没有意义的。手术毫无意义

另外,由于图形对象是一次性的,您应该将其放在使用块中,而不是手动处理。这保证了在异常情况下的正确处理:

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.
}

你应该认为这是一个固定的模式。

不,我没有指定,我想在图形上调用Price方法来制作图像。你能再解释一下如何解决这个问题吗?不,我没有指定,我在想调用graph上的Paint方法可以生成图像。你能再解释一下如何解决这个问题吗?