做一个简单的实时采集模拟数据的上位机问题,在panel控件当中实时画出波形曲线。
private void panel2_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Bitmap bmp = new Bitmap(panel2.ClientRectangle.Width, panel2.ClientRectangle.Height);//创建位图 Graphics BufPicture = Graphics.FromImage(bmp);//位图的图形对象 System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath(); e.Graphics.FillRectangle(Brushes.White, e.Graphics.ClipBounds); Point Positionpanel2 = panel2.Location; Point Positiongroupbox4 = groupBox4.Location; int panel2PX = Positionpanel2.X;//容器panel的X坐标 int panel2PY = Positionpanel2.Y;//容器panel的Y坐标 int groupbox4PX = Positiongroupbox4.X;//分组框的X坐标 int groupbox4PY = Positiongroupbox4.Y; for (int i = 0; i < panel2.ClientRectangle.Width / unit_drawing + 1; i++)//画出X轴 { BufPicture.DrawLine(GridPen, panel2PX + groupbox4PX + i * unit_drawing, panel2PY + groupbox4PY, panel2PX + groupbox4PX + i * unit_drawing, panel2PY + groupbox4PY + (panel2.ClientRectangle.Height / unit_drawing) * unit_drawing);//画出X轴线 if (i % 3 == 0) { gp.AddString((i * unit_drawing).ToString(), this.Font.FontFamily, (int)FontStyle.Regular, 12, new RectangleF(panel2PX + groupbox4PX + i * unit_drawing, panel2PY + groupbox4PY + panel2.ClientRectangle.Height + 5, 400, 50), null); }//加上X轴坐标值 } for (int i = 0; i < panel2.ClientRectangle.Height / unit_drawing + 1; i++)//画出Y轴 { BufPicture.DrawLine(GridPen, panel2PX + groupbox4PX, panel2PY + groupbox4PY + i * unit_drawing, panel2PX + groupbox4PX + (panel2.ClientRectangle.Width / unit_drawing) * unit_drawing, panel2PY + groupbox4PY + i * unit_drawing);//画线 if (i % 4 == 0) gp.AddString((i * 0.25).ToString(), this.Font.FontFamily, (int)FontStyle.Regular, 12, new RectangleF((panel2PX + groupbox4PX) / 2, -i * unit_drawing + panel2PY + groupbox4PY + panel2.ClientRectangle.Height - 5, 24, 190), null);//加上Y轴坐标值 } if (DataList.Count - 1 >= (this.ClientRectangle.Width - panel2PX - groupbox4PX) / unit_drawing)//假如数据量大于可容纳的数据量,即删除最左数据,波形动态显示 { DataList.RemoveRange(0, DataList.Count - (this.ClientRectangle.Width - panel2PX - groupbox4PX) / unit_drawing - 1); } for (int i = 0; i < DataList.Count - 1; i++) { BufPicture.DrawLine(Linepen, panel2PX + groupbox4PX + i * unit_drawing, panel2PY + groupbox4PY + panel2.ClientRectangle.Height - DataList[i], panel2PX + groupbox4PX + (i + 1) * unit_drawing, panel2PY + groupbox4PY + panel2.ClientRectangle.Height - DataList[i + 1]); //画出波形图 } g.Graphics.DrawImage(bmp, panel2PX + groupbox4PX, panel2PY + groupbox4PY, panel2.ClientRectangle.Width, panel2.ClientRectangle.Height);//将内存中画好的图复制到panel当中,最终实现双缓冲 e.Graphics.DrawPath(Pens.Black, gp); // }
实现双缓冲程序的思路就是,先本人在内存开辟了一个bitmp的区域,然后对应一个graphics对象,用这个graphics对象作图,最终复制到要显示的graphics对象中。实现双缓冲。但本人这样写了之后,X轴,Y轴和波形都不再显示。求大家指导下。
解决方案
5
30 行以前的格线绘制,不需要每次都进行
你可先画好后,保存于 bitmap 中作为容器的背景图
paint 事件中只画线,双不双缓存无所谓
你可先画好后,保存于 bitmap 中作为容器的背景图
paint 事件中只画线,双不双缓存无所谓
5
其实 大量的控件以及大量的画图产生的”闪烁”在winform中根本无法解决..
网上的全部的方案本人都测试过了根本不行.所以要从本质来解决问题.
例如你这个东西..实时的图形控件而已…..所以本人个人觉得没必要本人画,随意搜索一个第三方的用来足以
网上的全部的方案本人都测试过了根本不行.所以要从本质来解决问题.
例如你这个东西..实时的图形控件而已…..所以本人个人觉得没必要本人画,随意搜索一个第三方的用来足以
30
把坐标系画在bitmap上,每次都drawimage一番
双缓存的graphics不用每次都create一个,这样会闪烁
定义一个全局的BufferedGraphics graphBuffer,初始化语句为:
双缓存的graphics不用每次都create一个,这样会闪烁
定义一个全局的BufferedGraphics graphBuffer,初始化语句为:
graphBuffer = (new BufferedGraphicsContext()).Allocate(panel2.CreateGraphics(), panel2.DisplayRectangle);
每次画的时候取graphics
Graphics g = this.graphBuffer.Graphics;
然后drawimage,把坐标系作为背景,再画图案