求助C# GDI+双缓冲绘图闪烁的问题

z20110411 2016-08-31 08:59:48
做一个简单的实时采集模拟数据的上位机问题,在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轴和波形都不再显示。求大家指导下。
...全文
463 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
neu_2015 2017-04-16
  • 打赏
  • 举报
回复
请问您的这个 串口助手设计好了吗
z20110411 2016-09-05
  • 打赏
  • 举报
回复
引用 6 楼 u012948520 的回复:
画完之后记得调用显示
this.graphBuffer.Render();
十分感谢,按照这个做出来了,闪烁解决了。
z20110411 2016-09-02
  • 打赏
  • 举报
回复
引用 4 楼 diaodiaop 的回复:
其实 大量的控件以及大量的画图产生的"闪烁"在winform中根本无法解决.. 网上的所有的方案我都测试过了根本不行.所以要从本质来解决问题. 比如你这个东西..实时的图形控件而已.....所以我个人觉得没必要自己画,随意搜索一个第三方的用来足以
我读书少你不要骗我啊,我画实时曲线不用双缓冲绝对要闪的。
z20110411 2016-09-02
  • 打赏
  • 举报
回复
引用 6 楼 u012948520 的回复:
画完之后记得调用显示
this.graphBuffer.Render();
觉得好专业,这个肯定好用,我先试试。多谢哈
白衣如花 2016-09-01
  • 打赏
  • 举报
回复
画完之后记得调用显示
this.graphBuffer.Render();
白衣如花 2016-09-01
  • 打赏
  • 举报
回复
把坐标系画在bitmap上,每次都drawimage一番 双缓存的graphics不用每次都create一个,这样会闪烁 定义一个全局的BufferedGraphics graphBuffer,初始化语句为:
graphBuffer = (new BufferedGraphicsContext()).Allocate(panel2.CreateGraphics(), panel2.DisplayRectangle);
每次画的时候取graphics
Graphics g = this.graphBuffer.Graphics;
然后drawimage,把坐标系作为背景,再画图案
by_封爱 版主 2016-09-01
  • 打赏
  • 举报
回复
其实 大量的控件以及大量的画图产生的"闪烁"在winform中根本无法解决.. 网上的所有的方案我都测试过了根本不行.所以要从本质来解决问题. 比如你这个东西..实时的图形控件而已.....所以我个人觉得没必要自己画,随意搜索一个第三方的用来足以
z20110411 2016-08-31
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
30 行以前的格线绘制,不需要每次都进行 你可先画好后,保存于 bitmap 中作为容器的背景图 paint 事件中只画线,双不双缓存无所谓
谢谢版主大人啊,我改着试试。
xuzuning 2016-08-31
  • 打赏
  • 举报
回复
30 行以前的格线绘制,不需要每次都进行 你可先画好后,保存于 bitmap 中作为容器的背景图 paint 事件中只画线,双不双缓存无所谓
z20110411 2016-08-31
  • 打赏
  • 举报
回复
这是运行的结果

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧