Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
679 views
in Technique[技术] by (71.8m points)

c# - Drawing on PictureBox

in a UserControl I have a PictureBox and some other controls. For the user control which contains this picturebox named as Graph I have a method to draw a curve on this picture box:

    //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();
    }

When application starts, the axis are drawn. but when I call the DrawData method I get the exception that says bmp is null. What can be the problem?

I also want to be able to call DrawData multiple times to show multiple curves when user clicks some buttons. What is the best way to achive this?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You never assigned Image, right? If you want to draw on a PictureBox’ image you need to create this image first by assigning it a bitmap with the dimensions of the PictureBox:

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

You only need to do this once, the image can then be reused if you want to redraw whatever’s on there.

You can then subsequently use this image for drawing. For more information, refer to the documentation.

By the way, this is totally independent from drawing on the PictureBox in the Paint event handler. The latter draws on the control directly, while the Image serves as a backbuffer which is painted on the control automatically (but you do need to invoke Invalidate to trigger a redraw, after drawing on the backbuffer).

Furthermore, it makes no sense to re-assign the bitmap to the PictureBox.Image property after drawing. The operation is meaningless.

Something else, since the Graphics object is disposable, you should put it in a using block rather than disposing it manually. This guarantees correct disposing in the face of exceptions:

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

You should consider this as a fixed pattern.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...