C#开发WinForm版绘图程序,图元多了,漫游过程中屏幕闪烁太严重,我是在漫游过程中把所有图元重画一遍,有没有别的方法能消除闪烁问题?请各位高手指点,多谢!!!!!!!!!!!!!!!

解决方案 »

  1.   

    漫游时,不需要重绘,只移动的你的picturebox,漫游完毕后再去计算偏移量再重绘就好了
      

  2.   

    wawaku(一堆裤衩!) 兄弟 的方法我试过,的确可以,但漫游结束后再重绘,鼠标移动过程中图形还在原位置,总感觉效果不太好,不如实时移动。parkersh() 兄弟的方法没试过,可以试试。
    不知道哪有双缓冲图形技术的例子,如果哪为兄弟知道,烦劳贴点线索!谢谢!感谢二位!
      

  3.   

    查MSDN,有双缓冲的技术介绍,还有实现的例子。只要看懂这个例子,这个技术是不难的。
      

  4.   

    实现双缓冲的具体步骤:1、在内存中建立一块“虚拟画布”:Bitmap bmp = new Bitmap(600, 600);2、获取这块内存画布的Graphics引用:Graphics g = Graphics.FromImage(bmp);3、在这块内存画布上绘图:g.FillEllipse(brush, i * 10, j * 10, 10, 10);4、将内存画布画到窗口中this.CreateGraphics().DrawImage(bmp, 0, 0);
      

  5.   

    dyw31415926的例子不完整,如果这样的话效果依然不变;这样比较全面:
    1. 声明一个内存画布
    Bitmap map= new Bitmap(600, 600);2.生成一个画图函数 例如drawxxx(), 内容里面应该包括如下几语句(当然还有自己的别的画图逻辑)
    Graphics g = Graphics.FromImage(map);
    g.SmoothingMode = SmoothingMode.HighQuality; //高质量
    g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量
                                                        //当然还有反锯齿什么的.../*******************************************************
    *重点是下面这句, 实现双缓冲(this是继承自control的控件)
    ********************************************************/ this.SetStyle(ControlStyles.DoubleBuffer|ControlStyles.UserPaint|ControlStyles.AllPaintingInWmPaint,true);4.在控件的Onpaint里面写上
      e.Graphics.DrawImage(map,0,0);
      

  6.   

    双缓冲和只移动的picturebox解决不了楼主的问题这是一个效率问题,楼主只需加一个判断,即使1000万个元素,也可以尤如画1000个元素private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
    DrawAllObject(e.Graphics,e.ClipRectangle);
    }/// <summary>
    /// 在有效的工作区绘制所有对象,不可见的就不绘了以提高效率。
    /// </summary>
    /// <param name="g"></param>
    /// <param name="clientRectangle"></param>
    private void DrawAllObject(Graphics g,Rectangle clientRectangle)
    {
    g.Clear(System.Drawing.Color.White); Region regClip = g.Clip; g.Clip = new Region(clientRectangle);
             
             IMisGoldPrinter rectObj = null; for (int i = 0; i < m_ObjectList.Count; ++i)
    {
    rectObj = (IMisGoldPrinter)m_ObjectList[i];
               
    //rectObj.Draw(g);    //注意,这一句效率会极其低下
    //用如下判断后,对于大量对象,可以不画非可视区,因而效率提高
    if (clientRectangle.IntersectsWith(new Rectangle(rectObj.Point,rectObj.Size)))
    {
    rectObj.Draw(g);
    }
    } g.Clip = regClip;
    }
      

  7.   

    以上是一个改进方法,楼主加一个if (clientRectangle.IntersectsWith(可视区))试一试,效率明显改进。但是,并不是所有的时候要画所有的元素,特别是楼主拖动以便移动图元时,只需要在鼠标移动时,计算当前移动图元的矩形区,然后调用窗口方法Invalidate(图元矩形区),强制重绘制这么一小个矩形区,而不是调用Invalidate()绘整个窗口,这样效率更高了。在我的金质打印通新的设计器中,这是我的一些实践和楼主共享。
      

  8.   

    在picturebox上画就不会出现这样的问题了
      

  9.   

    使用双缓存,先作一张空的bitmap,然后在对这张bitmap作你象要得任何操作。最后用g.drawimage画出来
      

  10.   

    sunrobust(诚以待人严以律己) ( )/*******************************************************
    *重点是下面这句, 实现双缓冲(this是继承自control的控件)
    ********************************************************/ this.SetStyle(ControlStyles.DoubleBuffer|ControlStyles.UserPaint|ControlStyles.AllPaintingInWmPaint,true);---------------------------------
    这个是通过系统设置启动双缓冲的设置,但在应用中一般并不是这样做的,双缓冲是一种技术,或做法,并不是一种设置,你这样写了,并不会有效果的改善,你如果看过一些实际项目的做法时,你会觉得你这种写法都是怪怪的,呵呵,这里不是和你唱反调,咱们还是互相学习!!你可以写一些测试函数,比一下贴的效率就知道了.