在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
以在用户点击某些按钮时显示多条曲线。实现这个目标的最佳途径是什么?
谢谢
答案 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.
}
您应该将此视为固定模式。