Bitmap bitmap;//申明为类成员
Graphics graph;
private void createImage()
{//调用的时候先调用createImage方法
bitmap=new Bitmap(this.Width,this.Height);
graph=new Graphics.FromImage(bitmap);
}
private void updateImage()
{
bitmap=new Bitmap(this.Width,this.Height);//问题在于为什么一定要在此处对bitmap重新new,
//如果不重新new就显示不出线条
graph=new Graphics.FromImage(bitmap);
graph.DrawLine(pen,0,2,20,50);
this.BackgroundImage=bitmap;
}
//如果这样写就不会有图形
private void updateImage()
{
graph.DrawLine(pen,0,2,20,50);
this.BackgroundImage=bitmap;
}
如果你createImage()执行后立刻调用updateImage(),应该效果和重新new一样的,因为代码之间没有任何其它干预,你说的是什么特殊情况?
贴完整代码吧,这么两句话说不清你到底怎么写的。
private Bitmap bitmap;
private Graphics graph;
private Pen penWave = new Pen(Color.Lime);
private Pen penGrid = new Pen(Color.Gray);
protected override void OnLoad(EventArgs e)
{
//打开双缓冲,防止闪烁
DoubleBuffered = true;
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
bitmap = new Bitmap(this.Width, this.Height);
graph = Graphics.FromImage(bitmap);
DrawGrids(ref graph);
this.BackgroundImage = bitmap;
}
protected override void OnResize(EventArgs e)
{
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
bitmap = new Bitmap(this.Width, this.Height);
graph = Graphics.FromImage(bitmap);
DrawGrids(ref graph);
DrawDot(ref graph);
this.BackgroundImage = bitmap;
}
private void DrawGrids(ref Graphics g)
{//画网格
//pos,canvas_height都是变量,不重复贴了,不影响整体
g.DrawLine(penGrid, pos, 0, pos, canvas_height);//基本上都是这种代码,不重复贴,没做别的处理
}
private void DrawWave(ref Graphics g)
{
graph.DrawLine(penWave,0,2,20,50);//基本上都是这种,两点之间连线的,不重复贴代码了
}
//调用的时候,会先调用这个CreateImage()方法,再调用UpdateImage
//CreateImage只调用一次,UpdateImage会调用多次
public void CreateImage()
{
bitmap=new Bitmap(this.Width,this.Height);
graph=new Graphics.FromImage(bitmap);
}
public void UpdateImage()
{//经过反复试验,在这个方法里必须要对bitmap重新new,否则看不到两点间的连线
bitmap = new Bitmap(this.Width, this.Height);
graph = Graphics.FromImage(bitmap);
DrawDot(ref graph);
this.BackgroundImage = bitmap;
}
你上面给的代码里面CreateImage和UpdateImage压根没用到,你应该把不起作用的代码贴出来,把能作用的代码贴出来分析什么啊?
private void Form1_Load(object sender, EventArgs e)
{
gridCanvas.CreateImage();//调用的是类里的方法
}
//以下方法被执行
private void receive()
{
gridCanvas.UpdateImage();
}
你上面给的代码里面CreateImage和UpdateImage压根没用到,你应该把不起作用的代码贴出来,把能作用的代码贴出来分析什么啊?
你上面给的代码里面CreateImage和UpdateImage压根没用到,你应该把不起作用的代码贴出来,把能作用的代码贴出来分析什么啊?
private Bitmap bitmap;
private Graphics graph;
private Pen penWave = new Pen(Color.Lime);
private Pen penGrid = new Pen(Color.Gray);
protected override void OnLoad(EventArgs e)
{
//打开双缓冲,防止闪烁
DoubleBuffered = true;
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
CreateImage();
DrawGrids(ref graph);
this.BackgroundImage = bitmap;
}
protected override void OnResize(EventArgs e)
{
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
this.Refresh();
}
private void DrawGrids()
{//画网格
//pos,canvas_height都是变量,不重复贴了,不影响整体
graph.DrawLine(penGrid, pos, 0, pos, canvas_height);//基本上都是这种代码,不重复贴,没做别的处理
}
private void DrawWave()
{
graph.DrawLine(penWave,0,2,20,50);//基本上都是这种,两点之间连线的,不重复贴代码了
}
//调用的时候,会先调用这个CreateImage()方法,再调用UpdateImage
//CreateImage只调用一次,UpdateImage会调用多次
public void CreateImage()
{
bitmap=new Bitmap(this.Width,this.Height);
graph=new Graphics.FromImage(bitmap);
}
public void UpdateImage()
{//经过反复试验,在这个方法里必须要对bitmap重新new,否则看不到两点间的连线
DrawDot();
this.Refresh();
}
设定背景颜色的时候,重新new一下就好了。
原因就出在this.BackgroundImage和graph使用了同一个bitmap对象。
public void UpdateImage()
{//经过反复试验,在这个方法里必须要对bitmap重新new,否则看不到两点间的连线
DrawWave(ref graph);
this.BackgroundImage = new Bitmap(bitmap);
}
private Bitmap bitmap;
private Graphics graph;
private Pen penWave = new Pen(Color.Lime);
private Pen penGrid = new Pen(Color.Gray);
protected override void OnLoad(EventArgs e)
{
//打开双缓冲,防止闪烁
DoubleBuffered = true;
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
CreateImage();
DrawGrids(ref graph);
this.BackgroundImage = bitmap;
}
protected override void OnResize(EventArgs e)
{
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
this.Refresh();
}
private void DrawGrids()
{//画网格
//pos,canvas_height都是变量,不重复贴了,不影响整体
graph.DrawLine(penGrid, pos, 0, pos, canvas_height);//基本上都是这种代码,不重复贴,没做别的处理
}
private void DrawWave()
{
graph.DrawLine(penWave,0,2,20,50);//基本上都是这种,两点之间连线的,不重复贴代码了
}
//调用的时候,会先调用这个CreateImage()方法,再调用UpdateImage
//CreateImage只调用一次,UpdateImage会调用多次
public void CreateImage()
{
bitmap=new Bitmap(this.Width,this.Height);
graph=new Graphics.FromImage(bitmap);
}
public void UpdateImage()
{//经过反复试验,在这个方法里必须要对bitmap重新new,否则看不到两点间的连线
DrawDot();
this.Refresh();
}
改成酱紫应该没问题了。
private Bitmap bitmap;
private Graphics graph;
private Pen penWave = new Pen(Color.Lime);
private Pen penGrid = new Pen(Color.Gray);
protected override void OnLoad(EventArgs e)
{
//打开双缓冲,防止闪烁
DoubleBuffered = true;
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
CreateImage();
DrawGrids(ref graph);
this.BackgroundImage = bitmap;
}
protected override void OnResize(EventArgs e)
{
canvas_height = base.ClientSize.Height;
canvas_width = base.ClientSize.Width;
this.Refresh();
}
private void DrawGrids()
{//画网格
//pos,canvas_height都是变量,不重复贴了,不影响整体
graph.DrawLine(penGrid, pos, 0, pos, canvas_height);//基本上都是这种代码,不重复贴,没做别的处理
}
private void DrawWave()
{
graph.DrawLine(penWave,0,2,20,50);//基本上都是这种,两点之间连线的,不重复贴代码了
}
//调用的时候,会先调用这个CreateImage()方法,再调用UpdateImage
//CreateImage只调用一次,UpdateImage会调用多次
public void CreateImage()
{
bitmap=new Bitmap(this.Width,this.Height);
graph=new Graphics.FromImage(bitmap);
}
public void UpdateImage()
{//经过反复试验,在这个方法里必须要对bitmap重新new,否则看不到两点间的连线
DrawDot();
this.Refresh();
}
改成酱紫应该没问题了。
谢谢你的解答,调用Refresh是可以显示出图像的,请教下这是为什么呢,对同一个bitmap进行操作,这个bitmap已经作为背景图像了,再次操作的时候为啥设置BackgroundImage为bitmap不管用,要调用Reflesh才行呢?
谢谢你的解答,调用Refresh是可以显示出图像的,请教下这是为什么呢,对同一个bitmap进行操作,这个bitmap已经作为背景图像了,再次操作的时候为啥设置BackgroundImage为bitmap不管用,要调用Reflesh才行呢?
因为你的
this.BackgroundImage = bitmap;
bitmap是一个引用类型。当你再次设置 this.BackgroundImage = bitmap;的时候,其实什么都没做,因为 this.BackgroundImage所指向的内存地址已经是bitmap了。这个时候不会自动触发窗体print事件。当你在
this.BackgroundImage = bitmap;之前加了bitmap=new Bitmap()之后,bitmap的内存地址发生了重新分配,这样
BackgroundImage发现接收的内存地址发生了变化,于是触发了窗体print事件。
最终的原因还是因为:你没有找着对象。
谢谢你的解答,调用Refresh是可以显示出图像的,请教下这是为什么呢,对同一个bitmap进行操作,这个bitmap已经作为背景图像了,再次操作的时候为啥设置BackgroundImage为bitmap不管用,要调用Reflesh才行呢?
因为你的
this.BackgroundImage = bitmap;
bitmap是一个引用类型。当你再次设置 this.BackgroundImage = bitmap;的时候,其实什么都没做,因为 this.BackgroundImage所指向的内存地址已经是bitmap了。这个时候不会自动触发窗体print事件。当你在
this.BackgroundImage = bitmap;之前加了bitmap=new Bitmap()之后,bitmap的内存地址发生了重新分配,这样
BackgroundImage发现接收的内存地址发生了变化,于是触发了窗体print事件。
最终的原因还是因为:你没有找着对象。
好吧,意思就是说BackgroundImage指向了bitmap的引用地址,但是再次设置BackgroundImage的时候,编译器检测到指向的内存地址不变,即使bitmap里的东西发生了变化,也不会更新UI,大致是这个意思吧?感觉有点像是编译优化,在C里可以用volatile进行修饰防止编译器优化,对Bitmap用volatile修饰,发现不管用。。。。还是得刷新才行
private void updateImage()
{
graph.DrawLine(pen,0,2,20,50);
this.BackgroundImage=bitmap;
}
private void updateImage()
{
graph.DrawLine(pen,0,2,20,50);
this.BackgroundImage=bitmap;
OnBackgroundImageChanged(new EventArgs());
}
就是这个意思,因为.net中认为bitmap是一个非托管对象,所以不管是不是优化,都不会对bitmap进行检查。
另外你的代码里面 ref Graphics也是没有意义的,因为Graphics本身就是一个引用对象,不需要ref也是ref了。
private void updateImage()
{
graph.DrawLine(pen,0,2,20,50);
this.BackgroundImage=bitmap;
}
改为:
private void updateImage()
{
graph.DrawLine(pen,0,2,20,50);
this.BackgroundImage=bitmap;
OnBackgroundImageChanged(new EventArgs());
}
控件的BackgroundImage属性在设置值的时候,有一段判断语句:
if(this.BackgroundImage != value)
因此对于第二次的this.BackgroundImage=bitmap;操作是没有任何动作的。不过你可以人为地引发那个事件。