【C#】Winform 令人困擾的畫面閃爍問題解法
DoubleBuffered = true
如果 Control 沒有這個屬性,可以使用我下列擴充函式進行設定︰
public static void SetDoubleBuffered<T>(this T control) where T : Control
{
typeof(T).InvokeMember(
"DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
null,
control,
new object[] { true });
}
DoubleBuffered 針對 DataGridView 載入大量資料時特別有幫助,所以我通常都這樣使用︰
public class MyGridView : DataGridView { public MyGridView() { this.SetDoubleBuffered(); } }
DataGridView 載入大量資料時,拖拉 scrollbar 比較不會造成畫面閃爍,但對於畫面控制項閃爍沒什麼作用。
解決畫面控制項閃爍
在 Form 裡加入下列屬性 CreateParams,可以有效解決該畫面控制項閃爍的問題發生︰
public partial class MyForm : Form { protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } } public MyForm() { InitializeComponent(); } }
不過開啟該屬性時有個缺點,那就是如果是用在 MDI 等多個畫面重疊時,
當關閉當前Form時,當前Form的影像會覆蓋在後面準備顯示出來的Form上面,
必須重新調整畫面Size迫使Form重繪畫面,才能恢復正常,
有鑑於此,必需要監控畫面被激活時,強迫畫面重繪,因此解法如下︰
public partial class MyForm : Form { protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } } public MyForm() { InitializeComponent(); // 加入下面這行迫使該畫面被啟用時重繪畫面控制項 this.Activated += (sender, e) => { Invalidate(); }; } }
Thank you for your time.