private void InitDraw()
        {
            //int x = 10, y = 15, dx = 840, dy = 560;
            Bitmap bitmap = new Bitmap(this.panel2.ClientSize.Width, this.panel2.ClientSize.Height);
            Graphics g = Graphics.FromImage(bitmap);//将绘制内容画到bitmap中。
            g.Clear(Color.White);
            Pen blackPen = new Pen(Color.Black);//定义一只画笔
            SolidBrush redBrush = new SolidBrush(Color.Red);//单色画刷,填充形状            //先画矩形
            g.DrawRectangle(blackPen, 10, 15, 840, 560);//以坐标(10,15)为起点画一个宽840,高575的矩形
        
            //画分割线,
            for (int i = 0; i < 4; i++)
                g.DrawLine(blackPen, 10, 140 * i + 15, 850, 140 * i + 15);//(x,dy/4*i+y,dx+x,dy/4*i+y);            for (int j = 0; j < 4; j++)
            {//鼠标单击画线。
                //判断鼠标在那个通道上,
                if (m_x > 10 && m_y > 140 * j + 15 && m_y < 140 * (j + 1) + 15 && m_x < 850)
                {
                    g.DrawLine(blackPen, m_x, 140 * j + 15, m_x, 140 * (j + 1) + 15);
                    g.FillEllipse(redBrush, 15, 140 * j + 20, 10, 10);
                }
            }            for (int k = 0; k < 26;k++ )
            {//画底部坐标
                if (k % 5 == 0) 
                    g.DrawLine(blackPen, 10 + 33 * k, 568, 10 + 33 * k, 575);
                else
                    g.DrawLine(blackPen, 10 + 33 * k, 572, 10 + 33 * k, 575);
            }            //自定义虚线
            blackPen.DashPattern = new float[] { 2, 3 };//2表示虚线长度为2px,3表示虚线间隔为3px
            for (int i = 0; i < 4; i++)
            {
                g.DrawLine(blackPen, 10, 140 * i + 85, 850, 140 * i + 85);//(x,dy/4*i+(dy/8+y),dx+x,dy/4*i+(dy/8+y))
            }
            
            g.Dispose();
            blackPen.Dispose();
            redBrush.Dispose();
            Graphics gg = this.panel2.CreateGraphics(); //在tabPage1上绘图
            gg.DrawImage(bitmap,0,0);//将bitmap图片显示
            bitmap.Dispose();
            gg.Dispose();
        }
        //画采集曲线
        private void InitDraw_cur() 
        {
            //画采集的曲线
            //当前处于哪几个曲线,调文件画曲线
            //画采集波形,如果某道有数据就画,没有数据就不画
            int i = 0;
            byte j ;
            for (j = 1; j < 5; j++)
            {
                if (Trace[j] == true)//首先读通道数组,如果本道有数据,则画曲线
                {
                    short MaxAd = 1;
                    for (i = 0; i < TPR.SampLen; i++)
                    {
                        if (MaxAd < Math.Abs(Tdata[j, i]))
                            MaxAd = Math.Abs(Tdata[j, i]);
                        //bufw.Write(Fda[i]);//浮点数
                    }
                    //画曲线
                    int Cu = j - 1;
                    Graphics g = this.panel2.CreateGraphics();
                    Pen redPen = new Pen(Color.Red);
                    double dx = 0, dy0 = 0, dy1 = 0;
                    dx = (double)840 / TPR.SampLen;
                    for (i = 0; i < TPR.SampLen - 1; i++)
                    {
                        dy0 = (double)Tdata[j, i] / MaxAd;
                        dy1 = (double)Tdata[j, i + 1] / MaxAd;
                        g.DrawLine(redPen, 10 + (int)(dx * i), (int)(85 - dy0 * 40) + Cu * 140, 10 + (int)(dx * (i + 1)), (int)(85 - dy1 * 40) + Cu * 140);//46=98/2;中间分割线starX,starY,endX,endY
                    }
                    g.Dispose();
                    redPen.Dispose();
                }
            }   
        }private void panel2_Paint(object sender, PaintEventArgs e)
        {
            if (FormSty == "采集界面")
            {
                InitDraw();
                InitDraw_cur();
            }
            else if (FormSty == "单道界面")
            {
                InitDraw_sign();
                InitDraw_singCur();
            }
            else if (FormSty == "分析界面")
            {
                InitWave();
                InitWave_cur();
            }
        }       
        private void panel2_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)//单击鼠标左键
            {
                if (FormSty == "采集界面")
                {
                    m_x = e.X;//获取鼠标点击时x轴坐标
                    m_y = e.Y;//y坐标                    InitDraw();
                    InitDraw_cur();
                }
                if (FormSty == "单道界面")
                {
                    m_x = e.X;//获取鼠标点击时x轴坐标
                    m_y = e.Y;//y坐标                    InitDraw_sign();
                    InitDraw_singCur();
                }  
            }
        }        private void panel2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if(FormSty=="单道界面")
            {
                FormSty = "采集界面";
                InitDraw();
                InitDraw_cur();
                this.单道显示ToolStripMenuItem.Checked = false;
                this.多道显示ToolStripMenuItem.Checked = true;
            }
            else if (FormSty == "采集界面")
            {
                FormSty = "单道界面";
                InitDraw_sign();
                InitDraw_singCur();
                this.单道显示ToolStripMenuItem.Checked = true;
                this.多道显示ToolStripMenuItem.Checked = false;
            }
        }        private void panel2_MouseMove(object sender, MouseEventArgs e)
        {
            panel2_MouseDown(sender, e);
        }这样画出来之后,会很闪,本人新手,请大侠分析下代码。

解决方案 »

  1.   

    设置 Form 的 DoubleBuffer=true;打开缓冲
      

  2.   

    重载Panel控件,设置双缓冲。 
    构造函数里写
    this.DoubleBuffered = true
      

  3.   

    Panel.Backgroundimage=.....
    设置背景而不是在其上绘图
      

  4.   

    本人新手,不妥之处请拍。
    具体代码如下:首先自定义一个PANEL,代替你代码中的PANEL2,当然,接下来在主界面中需要添加之,添加的方法你肯定知道了。。委托,各种事件注册。。
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Drawing.Drawing2D;namespace 你的命名空间
    {
        public class DrawPanel : Control
        {
            public DrawPanel()
            {
                this.DoubleBuffered = true;
                this.SetStyle
                (
                   ControlStyles.OptimizedDoubleBuffer |
                   ControlStyles.ResizeRedraw, true
                );
                this.Paint += new PaintEventHandler(DrawPanel_Paint);
            }
    }在主界面中的构造函数中可以加入:
      //-----------------------DoubleBuffered------------------//
                this.SetStyle(
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.ResizeRedraw, true);
                this.SetStyle(ControlStyles.DoubleBuffer, true);
                this.SetStyle(ControlStyles.UserPaint, true);
                this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    你先尝试下。
      

  5.   


    学习,之后我的恶心的代码可以改善下。。全部是在panel上的。
      

  6.   

    一个最简单的方法就是把panel换成pictureBox这个控件就不会闪了
    /// <summary>
            /// 重绘事件
            /// </summary>
            /// <param name="e"></param>
            void drawPanel_Paint(object sender, PaintEventArgs e)
            {
                Bitmap bp = new Bitmap(this.picBoxMain.Width, this.picBoxMain.Height);
                //newGraphics = this.panelMain.CreateGraphics();
                newGraphics = Graphics.FromImage(bp);
                try
                {
                    SetStyle(ControlStyles.UserPaint, true);
                    SetStyle(ControlStyles.AllPaintingInWmPaint, true); //禁止擦除背景.
                    SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
                    // 消锯齿(可选项)
                    newGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    //高质量
                    newGraphics.SmoothingMode = SmoothingMode.HighQuality;
                    for (int i = 0; i < LineManager.ListLine.Count; i++)
                    {
                        Line line = LineManager.ListLine[i];
                        Pen p = new Pen(line.LineColor, line.LineSize);
                        newGraphics.DrawLine(p, line.StartPoint, line.EndPoint);
                    }
                    // 将缓冲位图绘制到输出
                    e.Graphics.DrawImage(bp, Point.Empty);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("MainForm-->drawPanel_Paint:" + ex.Message);
                }
                finally
                {
                    newGraphics.Dispose();
                }
            }
      

  7.   

    双缓冲不是SetStyle(ControlStyles.UserPaint, true);
                    SetStyle(ControlStyles.AllPaintingInWmPaint, true); //禁止擦除背景.
                    SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
    这么几句话设置就完了吧?this.panel2.CreateGraphics();这样得到Graphics,和e.Graphice。有很大的区别。
      

  8.   

    把panel换成pictureBox这个控件就不会闪了
      

  9.   

    .你看我代码了?  换成pic一样的效果。 
    在Panel_Paint里面用e.Graphics得到Graphics绘出来不会闪,
    我在自己方法里面只能用this.panel.creartGraphics.得到Graphics。画出来会闪。Bitmap bitmap = new Bitmap(this.panel2.ClientSize.Width, this.panel2.ClientSize.Height);
                Graphics g = Graphics.FromImage(bitmap);这样画出来效果也是不闪的,但加上了曲线就会闪,
      

  10.   

    要用双缓冲才行,要不多次绘制会闪烁。 先把你要画的东西绘制在一个Bitmap上面,然后把这个Bitmap 贴上就就行了。
      

  11.   


    就是需要多次绘制,不同的功能绘制不同的效果,都是画在同一个panel上面。
    求方案。
      

  12.   

    http://www.diybl.com/course/4_webprogram/asp.net/netjs/2008520/117339.html
    http://www.cnblogs.com/yuanermen/archive/2008/10/09/1307369.html