把从串口接收的数据传给绘图函数。Graphics gp = Graphics.FromHwnd(this.Handle);
获取窗体的Graphics对象实例。然后调用Graphics的方法进行绘图。
但是窗体被覆盖之后图形就不见了。我不想把绘图函数放进OnPaint()函数。
这样无法给绘图函数传递数据,无法实现动态绘图。请高手指点一二,谢谢!

解决方案 »

  1.   

    用doublebuffer来做缓冲
    参看
    http://blog.csdn.net/Knight94/archive/2006/08/18/1094078.aspx
      

  2.   

    可以用定义保存参数值变量的形式作为参数,还是可以在OnPaint里面写的。
      

  3.   

    用PicureBox画啊在内存中画好Bitmap,然后赋值给PictureBox.Image 对象
      

  4.   

    to Knight94(愚翁):双缓冲是解决闪烁问题的,和楼主的问题没关系
      

  5.   

    双缓冲不就是在内存中画好了,然后在画到图形界面上么?
    窗体被覆盖住图像就没有了啊。
    因为在OnPaint()中没有相应的画图动作啊。
    能否解释的详细点,谢谢。
      

  6.   

    to 因为在OnPaint()中没有相应的画图动作啊。
    能否解释的详细点,谢谢。用窗体同样大小来产生一个bitmap,然后在bitmap进行绘画。
    在form的paint事件中调用e.Graphics.DrawImage来显示。
      

  7.   

    to Knight94(愚翁) :
      区别于普通的边画边显示,就是画好了再显示呗,玩了几年图形了,这个怎会不知。在内存中画,途中不需要显示,绘制快,就不易感觉闪烁,当然也节约系统资源下面你来补充吧
      

  8.   

    paint 事件只有在窗体初始化,和某部分区域无效时才会调用。程序运行过程中,我要根据收到的数据来绘图,该怎么办?
      

  9.   

    doublebuffer除了能很好地避免绘制闪烁,此外还有,绘制操作简便,例如比较复杂的图形处理;还有一个好处,保存绘制内容信息也比较方便。
      

  10.   

    其实你给的例子也是doublebuffer的一种应用而已
      

  11.   

    to 程序运行过程中,我要根据收到的数据来绘图,该怎么办?修改bitmap即可,例如:
    Graphics g = Graphics.FromImage( yourBufferImage );
    //Draw data using "g"this.Invalidate();//Refresh form
      

  12.   

    那这个过程是由收到数据事件触发的,处理过程肯定是在数据处理过程中。
    那窗口被盖住之后,图像不就全都没有了。我试过把图像放在pictrueBox可以解决这个问题,但是不用这个控件就解决不了么?
      

  13.   

    to 那这个过程是由收到数据事件触发的,处理过程肯定是在数据处理过程中。
    那窗口被盖住之后,图像不就全都没有了。不是给你说了吗,你需要在Form的Paint事件中去画
    //Form paint event
    e.Graphics.DrawImage( yourBufferImage, new Point(0,0) );
      

  14.   

    你的意思是每次bufferImage更改就会自动调用窗体的paint事件么?
    试一试!!
      

  15.   

    buffer是在另外一个函数中更新的,怎么才能传递给Paint事件?
      

  16.   

    to buffer是在另外一个函数中更新的,怎么才能传递给Paint事件?定义为成员即可
      

  17.   

    愚翁老兄可否说详细点,小弟是C#新手。您说的定义成员是定义成全局变量么。还有一点疑问,怎样子做到buffer更新就能paint事件?谢谢
      

  18.   

    private Bitmap yourBufferImage;
    //in your form load event
    yourBufferImage = new Bitmap( this.ClientSize );//Init bitmap
      

  19.   

    还是那个问题,如何做到更新buffer里面的内容就可以调用Paint函数。
    实现实时绘图,请老大解释一下,谢谢!
      

  20.   

    实时在bitmap里绘图,OnPaint里只要显示这个位图就可以了
      

  21.   

    to 还是那个问题,如何做到更新buffer里面的内容就可以调用Paint函数。
    实现实时绘图,请老大解释一下,谢谢!yun~仔细看前面的代码,在处理完buffer后,调用Invalidate方法来使窗体刷新。
      

  22.   

    专门写个函数把你绘图操作放进去,比如 Draw() 吧。
    数据更新的时候,就是你原来画图的地方,Draw() 一下
    OnPaint() 里,Draw() 一下。
      

  23.   

    绘图逻辑还是写OnPaint里。
    需要重绘的时候Invalidate()。
      

  24.   

    声明一个Bitmap对象,绘图的时候先在这个Bitmap上绘图,然后复制上窗体上DrawImage,OnPaint()里就直接贴上这个Bitmap就行了,
      

  25.   

    所有的绘图操作都在内存中绘制到一个位图上,OnPaint时绘制一下位图,在你的主代码中也显示该位图就行了。
      

  26.   

    程序员的福音---去www.mylinux.com.cn看看吧,程序员的图书馆
    最全面的程序开发资料网www.mylinux.com.cn
    包罗java,linux,数据库,安全等等技术资料,更有众多软件外包项目我们的qq群:15096318 学习程序的都可以来华资软件作为一家专业的软件公司,现公开承接各种软件外包项目.
    www.mylinux.com.cn国内最大的网上软件加工厂,提供最完善的软件外包服务,采用流水型操作流程。中国软件业的发展不缺人才也不缺资金,缺的是人才的组织和管理,MyLinux平台的建设解决了软件人才的组织和管理问题,将每一项目最合适的软件开发人才以最有效率的形式组织在一起,从而取得1+1〉2的效果。
      MyLinux(www. MyLinux.com.cn)由上海巨灵信息技术有限公司主办,是目前国内最大的网上软件加工厂,该网站将提供最完善的软件外包服务,采用流水型操作流程。详情请登陆www. MyLinux.com.cn
    您可把您的具体要求发布在http://www.mylinux.com.cn/guiderAction.do?type=7上,并留下联系方式,我们网站的技术部门和客服会在第一时间审核安排.~~
      

  27.   

    Bitmap m_Off = new Bitmap(Width, Height);
    Graphics gp = Graphics.FromImage(m_Off);
    // 在这个上画图// OnPaint里
    if (m_Off != null)
    pe.Graphics.DrawImage(m_Off, 0, 0);
      

  28.   

    然后调用Graphics的方法进行绘图。
    但是窗体被覆盖之后图形就不见了。
    ================因为不是在onpaint中写的我不想把绘图函数放进OnPaint()函数。
    这样无法给绘图函数传递数据,无法实现动态绘图。
    ================楼上有人说用picturebox,很好,你还可以控制picturebox的visible属性
      

  29.   

    真是不比不知道!我原先在OnPaint方法里面画图,一个400×360象素的图片,打开一次需要25秒。采用了先在Bitmap里面生成,然后再把Bitmap赋给PictureBox的方式之后,现在只需要1秒就打开了!!还是“愚翁”的办法好呀!书上都没有看的。如果可以的话我情愿再加50分送给愚翁老兄。
      

  30.   

    首先,这个绘制操作一定要在Paint事件处理方法中进行,绝无二法。
    第二,用不用PictureBox不是问题。最主要的是在数据更新时重绘。解决方法是:在要绘画的窗口类中增加一个保存绘制数据的属性,比如你是用PictureBox则:class MyPictureBox : PictureBox
    {
       private PaintData data; 
       public PaintData PaintData
       {
           set
           {
               //设置数据。
               data = value;
               Invalidate();
            }
            get
            {
            }
        }}
    就是在数据更新时,重新绘制即可。很简单的一个问题。一般AutoCad或类似的软件基本都是这样一个思路来解决这个问题的。
      

  31.   

    我这个比较完整:窗体上有一个picturebox,二个button按钮,在picturebox上画一个表,并在表上绘线。
    //***************************定义画标题的类********************************//
    private void DrwTtl(Graphics g)
    {
             string str1 = "车站综合技术作业表";
             FontFamily fntFam1 = new FontFamily("宋体");
    Font myFnt1 = new Font(fntFam1,36,FontStyle.Bold,GraphicsUnit.Pixel);
    SolidBrush bsh1 = new SolidBrush(Color.Green);
    Rectangle fw1 = new Rectangle(8,8,600,50);
    StringFormat fmt1 = new StringFormat();
    fmt1.Alignment = StringAlignment.Near;
    fmt1.LineAlignment = StringAlignment.Center; string str2 = "时间:" + dtp_ks.Text.ToString() + tx_ks.Text + "点 -- " + dtp_js.Text.ToString() + tx_js.Text + "点";
    FontFamily fntFam2 = new FontFamily("宋体");
    Font myFnt2 = new Font(fntFam2,18,FontStyle.Bold,GraphicsUnit.Pixel);
    SolidBrush bsh2 = new SolidBrush(Color.Green);
    Rectangle fw2 = new Rectangle(8,26,600,72);
    StringFormat fmt2 = new StringFormat();
    fmt2.Alignment = StringAlignment.Near;
    fmt2.LineAlignment = StringAlignment.Center;
    g.DrawString(str1,myFnt1,bsh1,fw1,fmt1);
    g.DrawString(str2,myFnt2,bsh2,fw2,fmt2);
    bsh1.Dispose();
    bsh2.Dispose();
    }//****************************定义画表头的类*******************************//
    private void DrwTblHeader(Graphics g)
    {
    }//****************************定义画空表的类******************************//
    private void DrwGrid(Graphics g)
    {
    Pen grnPen = new Pen(Color.Green,1);
    //水平线
    for(int i=72;i<bmp.Height+1;i+=20)
    {
    g.DrawLine(grnPen,0,i,bmp.Width-24,i);
    }
    //垂直线
    for(int j=0;j<bmp.Width+1;j+=24)
    {
    g.DrawLine(grnPen,j,72,j,bmp.Height-10);
    }
    grnPen.Dispose();
    }//*****************定义画线的类***********************//
    private void DrwLcdd(PointF pnt1,PointF pnt2,PointF pnt3,PointF pnt4,string ddcc,int ddcs)
    {
    pnt1 = new PointF(10.0f,10.0f);
             pnt2 = new PointF(15.0f,30.0f);
    pnt3 = new PointF(15.0f,100.0f);
    pnt4 = new PointF(100.0f,100.0f); ddcc = "23456";
    ddcs = 23;
    }private Bitmap bmp = null;private void Paper_Paint(object sender,PaintEventArgs pe)
    {
    if (bmp != null)
    pe.Graphics.DrawImage(bmp, 0, 0);
    }private void button1_Click(object sender, System.EventArgs e)
    { Graphics g = this.Paper.CreateGraphics();
    g.Clear(Color.White); //创建一个临时绘图表面
    bmp = new Bitmap(this.Paper.Width,this.Paper.Height);
    Graphics gl = Graphics.FromImage(bmp); DrwTtl(gl);
    DrwGrid(gl);

    g.DrawImage(bmp,0,0);
    g.Dispose();
    gl.Dispose();
    // bmp.Dispose();}private void button2_Click(object sender, System.EventArgs e)
    {
    PointF pnt1,pnt2,pnt3,pnt4;
    string ddcc;int ddcs;
    pnt1 = new PointF(10.0f,10.0f);
    pnt2 = new PointF(15.0f,30.0f);
    pnt3 = new PointF(15.0f,100.0f);
    pnt4 = new PointF(100.0f,100.0f);
    PointF[] pnts = {pnt1,pnt2,pnt3,pnt4}; ddcc = "23456";
    ddcs = 23; if(bmp != null)
    {
    Graphics g = this.Paper.CreateGraphics();
    g.Clear(Color.White); Graphics gl = Graphics.FromImage(bmp);
    Pen bluPen = new Pen(Color.Blue,2);
    gl.DrawLines(bluPen,pnts);
    g.DrawImage(bmp,0,0);
    g.Dispose();
    gl.Dispose(); }}