日期:2014-05-20  浏览次数:20939 次

WinForm 你为什么这么闪?
主页面使用了背景图和带图片的按钮6个,在运行和重绘时背景图上的按钮都是一个一个重绘,整个软件重绘时如同百叶窗一样!找了N多资料,也使用了                         this.DoubleBuffered   =   true;
                        this.SetStyle(ControlStyles.UserPaint   |   ControlStyles.AllPaintingInWmPaint   |   ControlStyles.OptimizedDoubleBuffer,   true);

但是问题依然!!请教个位大侠如何解决这个问题!!

                protected   override   void   OnPaint(PaintEventArgs   e)
                {

                }

如何重写重绘事件可以解决这个问题1!

------解决方案--------------------
1.用双缓冲

2.局部重绘
------解决方案--------------------
主要是背景图片的问题,试试用一个Picturebox Fill整个窗体,再设置PictureBox的Image为你想显示的背景图

BackGroundImage显示比Image显示刷新慢
------解决方案--------------------
比如说百叶窗,第一次变宽度的10%,你就重绘这10%的页面
第二次变10~20 你就重绘这一部分
这样可以提高效率减轻闪烁
------解决方案--------------------
界面上的控件尽量的少是关键!
------解决方案--------------------
OnPaint事件只有在窗体Resize的时候或者重新Load的时候或者调用Invalidata()的时候才会触发,知道了这个原则你就检查你的代码吧!
------解决方案--------------------
每个子控件变化,父控件就要重绘一下,所以就慢了

应该在设置一些属性前, 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);
------解决方案--------------------
具体怎么写要看你的代码要怎么绘了...
------解决方案--------------------
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);
------解决方案--------------------
同病相怜!我想有没有简单一点的方法?比如,等整个窗口绘制完成以后,再显示出来?
------解决方案--------------------
怪不得WPF开始把显示任务全交给显卡上的GPU了。