C# 控件闪烁问题的解决
说一下解决C#下控件闪烁的几个问题,如下:
listview和datagridview显示数据闪烁
自定义控件的显示闪烁
listbox滚动条拖动闪烁
面板中控件过多的闪烁
propertyGrid点击和修改项目缓慢的问题
richtextbox控件的刷新显示问题
此类问题对于界面复杂规模比较大的程序感觉更明显。
另外我们的经验是你需要把程序拿到一个古董级别电脑上去复现上述问题及判断解决方案是否有效果。
listview和datagridview显示数据闪烁
解决方法是使用双缓冲,见下面代码
public static class DoubleBufferDataGridView{ /// <summary> /// 双缓冲,解决闪烁问题 /// </summary> /// <param name="dgv"></param> /// <param name="flag"></param> public static void DoubleBufferedDataGirdView(this DataGridView dgv, bool flag) { Type dgvType = dgv.GetType(); PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi.SetValue(dgv, flag, null); }}public static class DoubleBufferListView{ /// <summary> /// 双缓冲,解决闪烁问题 /// </summary> /// <param name="lv"></param> /// <param name="flag"></param> public static void DoubleBufferedListView(this ListView lv, bool flag) { Type lvType = lv.GetType(); PropertyInfo pi = lvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi.SetValue(lv, flag, null); }}//调用方法public Form1(){ InitializeComponent(); DataGridView1.DoubleBufferedDataGirdView(true);}
自定义控件的显示闪烁
此法是解决在 winform中动态添加自定义控件时,可能会出现闪烁的问题。
例如往FlowLayoutPanel控件(容器控件)中添加自定义控件。
1. 在添加自定义控件的Form中添加如下代码:
开启界面双缓冲 解决窗体切换闪屏问题
protected override CreateParams CreateParams{ get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; }}
2. 在自定义控件中添加如下代码:
protected override CreateParams CreateParams{ get { CreateParams cp = base.CreateParams; cp.ExStyle &= ~0x02000000; return cp; }}
listbox滚动条拖动闪烁
1. 禁止背景重绘消息
protected override void WndProc(ref Message m) { if (m.Msg == 0x0014) // 禁掉清除背景消息 return; base.WndProc(ref m); }
2. 使用控件的BeginUpdate 和 EndUpdate 方法
通过使用BeginUpdate 和 EndUpdate 方法,可以在对控件进行大数据填充时,
避免在应用这些更改时让控件经常重新绘制自身。
此类重新绘制会导致性能显著降低,并且用户界面闪烁且不反应。
BeginUpdate在许多控件里也可以隐式调用。
它就是控件的 AddRange 方法,使用它将自动为您调用 BeginUpdate 和 EndUpdate 方法。
面板中控件过多的闪烁
此法解决窗体中控件过多的闪烁
1. 开启界面双缓冲 解决窗体切换闪屏问题
protected override CreateParams CreateParams{ get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; }}
2. 使用自定义的panel
public partial class MyPanel : Panel { protected override void OnPaintBackground(PaintEventArgs e) { //do not allow the background to be painted } /**#region 开启界面双缓冲 解决窗体切换闪屏问题 //下面的代码许加在MDI窗体中 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } } #endregion protected override void WndProc(ref Message m) { if (m.Msg == 0x0014) // 禁掉清除背景消息 return; base.WndProc(ref m); } **/ protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { // 使用双缓冲 this.DoubleBuffered = true; // 背景重绘移动到此 if (this.BackgroundImage != null) { e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; e.Graphics.DrawImage( this.BackgroundImage, new System.Drawing.Rectangle(0, 0, this.Width, this.Height), 0, 0, this.BackgroundImage.Width, this.BackgroundImage.Height, System.Drawing.GraphicsUnit.Pixel); } base.OnPaint(e); } }
3. 在ui底层重绘每次会清除画布,然后再全部重新绘制,这是导致闪烁最主要的原因之一。
下面方法是重载消息发送函数操作,禁掉这条消息。至于有什么副作用,各位见到后可以告诉勇哥。
protected override void WndProc(ref Message m) { if (m.Msg == 0x0014) // 禁掉清除背景消息 return; base.WndProc(ref m); }
propertyGrid点击和修改项目缓慢的问题
此问题请见贴子《C#的propertygrid控件,选择和修改项目时很慢》
2022/4/6 注:
另外发现在mdi主窗体使用下面代码,也是造成propertygrid控件修改项目很慢的主要原因。(做梦也想不到会有影响)
//protected override CreateParams CreateParams //{ // get // { // CreateParams cp = base.CreateParams; // cp.ExStyle |= 0x02000000; // return cp; // } //}
richtextbox控件的刷新显示问题
此控件如果想更新内容,直接给text赋值就可以了。
但是如果你用定时器持续更新,是不是发现滚动条无法下拉?
其实是可以的,关键是你拉滚动条时不要把光标定位到richtextbox控件里面,因此,你需要点击面板上其它位置,让焦点不位于此控件就可以拉动滚动条了。
要注意的地方:
(1)不要在mdi主窗体使用下面代码
//protected override CreateParams CreateParams //{ // get // { // CreateParams cp = base.CreateParams; // cp.ExStyle |= 0x02000000; // return cp; // } //}
其后果就是当改变子窗体的大小时,(而这个窗体有一个容器,显示有动态载入的控件)有可能会让容器显示为空白。
或者有可能最小化再恢复窗体时出现这种空白的问题。
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!