再谈向窗口动态生成控件闪烁的问题
开发平台:VS2019
语言:C#
近日做个项目,需要在窗口中生成一些picturebox,然后插入到TableLayoutPanel(picTableLayout)中,以前做过同样的事情,肯定会遇到窗口闪烁且控件插入慢的问题,网上的方法大致描述如下
1、使用控件自身的方法
1.1插入前调用
picTableLayout.SuspendLayout();
1.2插入后调用
picTableLayout.ResumeLayout();
结果:没有什么鸟用
2、在窗口中重载属性
2.1 在窗口中重载父类的属性CreateParams
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } }
2.2 重载PictureBox控件(ExPictureBox)
在ExPictureBox中重载父类CreateParams属性
protected override CreateParams CreateParams { get { var parms = base.CreateParams; parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN return parms; } }
结果:如果没有意外,达到预期的效果,屏不闪了,动态加载控件速度快了
3、在使用第三方皮肤控件后 (CSkin.DLL)
使用(2)中的方法,结果各种意想不到:窗口不能最大化,窗口不能拖动,窗口上其它控件莫名其妙地 “消失”,界面卡死,等等。。。。。。。一系列问题
无奈,最后在网上找到Windows Api方式,终于解决了困扰许久的问题,不敢独享。
3.1Windows API声明
public static class WinApiHelper { [System.Runtime.InteropServices.DllImport("user32")] public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam); public const int WM_SETREDRAW = 0xB; }
3.2动态插入控件前调用
WinApiHelper.SendMessage(this.picTableLayout.Handle, WinApiHelper.WM_SETREDRAW, 0, IntPtr.Zero);//禁止重绘
3.3动态插入控件后调用
WinApiHelper.SendMessage(this.picTableLayout.Handle, WinApiHelper.WM_SETREDRAW, 1, IntPtr.Zero);//允许重绘 this.picTableLayout.Refresh();
OK了,暂时没有发现后遗症。