主页面使用了背景图和带图片的按钮6个,在运行和重绘时背景图上的按钮都是一个一个重绘,整个软件重绘时如同百叶窗一样!找了N多资料,也使用了            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);但是问题依然!!请教个位大侠如何解决这个问题!!        protected override void OnPaint(PaintEventArgs e)
        {        }如何重写重绘事件可以解决这个问题1!

解决方案 »

  1.   

    主要是背景图片的问题,试试用一个Picturebox Fill整个窗体,再设置PictureBox的Image为你想显示的背景图BackGroundImage显示比Image显示刷新慢
      

  2.   

    OnPaint事件只有在窗体Resize的时候或者重新Load的时候或者调用Invalidata()的时候才会触发,知道了这个原则你就检查你的代码吧!
      

  3.   

    owennol()  谢谢提醒!!搞了几个月winform了!!被这个疏忽给忽悠了很多天!!郁闷!!
    其实原来也想这么做,不过没测试!谢谢大家的帮助!
      

  4.   

    那么局部重绘技术,应该怎么写?有没有相关的例子研究?大家帮忙呀!!这个问题是.NET的老大难问题呀!!
      

  5.   

    每个子控件变化,父控件就要重绘一下,所以就慢了应该在设置一些属性前, SuspendLayout(),最后ResumeLayout();控件里面:const int WM_SETREDRAW = 0xB;[DllImport("User32")]
            static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);        private void SetRedraw(IntPtr handle, bool on)
            {
                SendMessage(handle, WM_SETREDRAW, on ? 1 : 0, 0);
            }
    SetRedraw(MyControl.Handle, false);SetRedraw(MyControl.Handle, true);
      

  6.   

    SuspendLayout(),最后ResumeLayout();现在VS2005都是自己加这段代码的!SetRedraw  这个应该怎么用?
      

  7.   

    float percent;                Rectangle newValueRect = this.ClientRectangle;
                    Rectangle oldValueRect = this.ClientRectangle;                percent = (float)(val - min) / (max - min);
                    newValueRect.Width = (int)((float)newValueRect.Width * percent);                percent = (float)(oldVal - min) / (float)(max - min);
                    oldValueRect.Width = (int)((float)oldValueRect.Width * percent);                Rectangle updateRect = new Rectangle();                if (newValueRect.Width > oldValueRect.Width)
                    {
                        updateRect.X = oldValueRect.Size.Width;
                        updateRect.Width = newValueRect.Width - oldValueRect.Width;
                    }
                    else
                    {
                        updateRect.X = newValueRect.Size.Width;
                        updateRect.Width = oldValueRect.Width - newValueRect.Width;
                    }                updateRect.Height = this.Height;                this.Invalidate(updateRect);
      

  8.   

    void CMyTreeCtrl::OnPaint()
    {
    CPaintDC dc(this); // device context for painting
    CRect rcclient;
    GetClientRect(&rcclient);// create a compatible memory dc
    CDC memdc;
    memdc.CreateCompatibleDC(&dc);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
    memdc.SelectObject( &bitmap );
    CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);
    CDC maskdc;
    maskdc.CreateCompatibleDC(&dc);
    CBitmap maskbitmap;
    maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
    maskdc.SelectObject( &maskbitmap );
    maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,
    rcclient.left, rcclient.top, SRCCOPY);
    CBrush brush;
    brush.CreatePatternBrush(&m_bitmap);
    dc.FillRect(rcclient, &brush);
    memdc.SetBkColor(RGB(0,0,0));
    memdc.SetTextColor(RGB(255,255,255));
    memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
    dc.SetBkColor(RGB(255,255,255));
    dc.SetTextColor(RGB(0,0,0));
    dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
    dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top,SRCPAINT);
    brush.DeleteObject();
    }
    VC中实现带有背景位图的树型控件中一节!!不过看的有点乱!!
    FAQ-C#窗体的刷新问题 
    http://www.cnblogs.com/sammy1983/articles/259459.html
    这个没看出有什么作用!!如果我要重绘的是按钮.那么我如何做呢?大侠们给点提示,或者事例最好!!这个问题我找了很多资料有没有找到方法!!都说的很模糊!!
      

  9.   

    Red_angelX(当你XX你会想起谁)  这段代码好像是局部重绘是不是? 我应该放入OnPaint内?
      

  10.   

    怪不得WPF开始把显示任务全交给显卡上的GPU了。
      

  11.   

    用这个api,hwndLock为窗口句柄,完成后传null参数而解除锁定   
        
      [DllImport("user32.dll",   EntryPoint="LockWindowUpdate")]   
      public   static   extern   int   LockWindowUpdate   (   
      IntPtr   hwndLock   
      );
      

  12.   

    jijl2001(jijl2001)  我看到有介绍用这个的,虽然有弊病!!但是这个用起来怎么样?如何正确使用?
      

  13.   

    如果你的按钮继承自System.Windows.Forms.Button ,设置button.DoubleBuffered = true
    因为是保护属性,继承一下再设置。
      

  14.   

    慢,是.NET的特点,除了慢还是他吗的慢.WIN方面简直是失败中的失败.
      

  15.   

    不如自己做个控件
    在内部自己画,用drawfromImage之类的东西,把你要的这批加进去。
    比较省资源,也比较快
      

  16.   

    不知道能否这样,用PictureBox替代按钮,每次的绘制都在内存上绘制。如何绘制到屏幕就无所谓了。也就是这样
    1。构造的时候,创建一个和控件一样尺寸的Bitmap对象,用这个对象作为PictureBox的Image属性。
    2。Graphics.FromImage(BitmapObject).Draw....
    3。执行控件.OnPaint或者发送消息给控件(WM_PAINT)