为什么我在某些函数里不能画图?比如form的构造函数,Form1_Load函数,甚至于Form_Paint还得用e.Graphics才能使用,CreateGraphics()都没反应。谁懂得GDI这方面的原理?

解决方案 »

  1.   

    paint事件,因为是画图事件,事件参数默认提供一个画布(graphics);
    如果没有就需要自己创建了,在控件上画图:graphics g=control.creategraphics();
    图片的话:graphics g=graphics.fromimage(image1);
    还有不要在构造函数里面画控件,会出错(句柄未创建)
      

  2.   


        需要注意画图程序执行的时间,比方说你的画图在构造函数“public Form1()”或窗体加载函数“Form1_Load”中,因为这两个函数都是在“private void Form1_Paint”之前执行的,就是说即使你画图成功也会被“private void Form1_Paint”清掉。鉴于这种情况,你可以把画图程序写在“Form1_Paint”中,不过这样有个问题就是当Form1中任意一个控件发生改变(颜色,大小,位置等)时,都会触发“Form1_Paint”事件而导致图片重绘。
        对于e.Graphics和CreateGraphics,我的理解是先定义一块画图板,然后在上面进行绘图操作。
      

  3.   

    其他函数为啥不行呢?难道graphics 有特殊限制?
      

  4.   

    使用GDI绘图,每个控件表面上的图形并不是持久的,而是在呈现的时候绘制的。在呈现控件的时候,Windows会给控件发送WM_PAINT消息,也就引发了我们熟悉的Paint事件,只有在这个事件里绘制图像才是有效的。
      

  5.   

    对于重绘的情况,我们可以定义OnPaint方法,这个方法是Control类里面用来执行Paint事件的方法,重写此方法可以避免重绘现象发生
      

  6.   

    Graphics不是单独创建的对象吗?怎么还需要触发Paint事件?
      

  7.   

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
                Image img = Image.FromFile(@"C:\Documents and Settings\Administrator\桌面\头像\fate1.jpg");
                Brush b1 = new TextureBrush(img);
                g = e.Graphics;  //和下面一行有差别,下面那行会一闪而过,这行代码不会。求教
                //g = this.pictureBox1.CreateGraphics();
                g.DrawImage(img, 10, 10);
            }
      

  8.   

    前面说过了,控件表面的图像不是持久的,那就意味着当控件的某个区域无效以后要重新绘制。那什么时候会无效呢,比如当一个窗口从最小化还原,或者被其它窗体遮挡的部分又显示出来,或者以编程的方式强制失效。Paint事件是在失效以后重绘时引发的事件,也就是每一次需要重绘都会被调用,如果在这个事件处理程序里写入绘制的代码,那图像不就看起来是持久的嘛。
    你可以自己写一段代码来比较一下,比如在窗体上画一个圆,然后以两个方式触发,一是按钮点击以后用CreateGraphics创建Graphics,二是Paint事件。第一种方式的确能够画上,但你试着最小化再还原,或者把窗体移出屏幕后再移回来就会发现圆不见了,需要再点一下按钮才能出现。而对于第二种方式,无论怎么折腾,圆依然存在。