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

.Net技术 码拜 4年前 (2016-09-14) 943次浏览
做一个简单的实时采集模拟数据的上位机问题,在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 事件中只画线,双不双缓存无所谓

5

其实 大量的控件以及大量的画图产生的”闪烁”在winform中根本无法解决..
网上的全部的方案本人都测试过了根本不行.所以要从本质来解决问题.
例如你这个东西..实时的图形控件而已…..所以本人个人觉得没必要本人画,随意搜索一个第三方的用来足以
求帮助C# GDI+双缓冲绘图闪烁的问题

30

把坐标系画在bitmap上,每次都drawimage一番
双缓存的graphics不用每次都create一个,这样会闪烁
定义一个全局的BufferedGraphics graphBuffer,初始化语句为:

graphBuffer = (new BufferedGraphicsContext()).Allocate(panel2.CreateGraphics(), panel2.DisplayRectangle);

每次画的时候取graphics

Graphics g = this.graphBuffer.Graphics;

然后drawimage,把坐标系作为背景,再画图案


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明求帮助C# GDI+双缓冲绘图闪烁的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)