C#窗口閃爍問題解決
https://www.cnblogs.com/AndyDai/p/5203798.html
開發WinForm 程序時經常會遇到閃屏的問題,這會給用戶造成很差的使用體驗,所以必須妥善解決好這個問題。
首先,我們先要找出閃屏的原因,就我目前遇到的問題而言,其原因真是五花八門。
主要的原因有:使用了很多的組件導致加載緩慢,使用了性能差的組件(PictureBox、Button等)。
所以,不論開發者的水平如何,微軟給我們也挖了坑的。
對於控件太多造成的閃屏,其原因有兩個:
1. 繪制控件時,Windows 會給控件發送兩個消息。第一個是WM_ERASEBKGND消息,它會觸發OnPaintBackground方法,繪制控件背景。
第二個是WM_PAINT消息,它會觸發 OnPaint()方法,繪制控件界面。當繪制很慢的時候,會先看到背景,然後才看到界面,這樣造成閃爍。
解決方案:在構造方法中設置 ControlStyles 的OptimizedDoubleBuffer 和AllPaintingInWmPaint為True,完全啟用雙緩沖。
啟用雙緩沖的首選方法是將該控件的 DoubleBuffered 屬性設置為 true,這會產生同樣的結果,原因不細說了。
this
.SetStyle(ControlStyles.AllPaintingInWmPaint,
true
);
this
.SetStyle(ControlStyles.OptimizedDoubleBuffer,
true
);
2. 有很多控件的窗體需要很長時間來繪制。特別是在它使用性能很差的PictureBox、Button等時。一旦你加上50多個的控件,閃屏就開始變得明顯了。
窗體會先繪制其自身背景,並在控件所在地方留下"洞"。這些"洞"通常是白色的,當你使用Opacity 或Transparency是黑色的。
然後每個控件被繪制後,就填充在"洞"中。這種視覺效果是很醜陋的,而且在WinForm 中沒有現成的解決方案。
雙緩沖也不能解決它,因為它只適用於一個單一的控件,而不是一組復合控件。
解決方案:設置CreateParams的ExStyle為ExStyle 為 0x02000000 (WS_EX_COMPOSITED)。
設置了這個值之後XP(其他系統好像也可以,沒有考證)會把窗體和它的子窗體都開啟雙緩沖。
protected
override
CreateParams CreateParams {
get
{
CreateParams cp =
base
.CreateParams;
cp.ExStyle |= 0x02000000;
return
cp;
}
}
這裏有一些需要註意的地方:這種方式並不會加快繪制的過程。當發生繪制時,窗體只是停留在不可見的狀態,當繪制完成後就會在屏幕上彈出。
這時窗體的Opacity or TransparencyKey 是不會起作用的,窗體的輪廓是可見的,在繪制區域會出現一個醜陋的黑色矩形框。
要解決這個問題,最好使用計時器來增加不透明度值到99%,以使其在繪制後可見,這樣用戶就不會看到黑色矩形了。
public partial class FormDemo : Form { private Timer Timer = null; public FormDemo() { InitializeComponent(); Timer = new Timer() { Interval = 100 }; Timer.Tick += new EventHandler(Timer_Tick); base.Opacity = 0; Timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { if (this.Opacity >= 1) { Timer.Stop(); } else { base.Opacity += 0.2; } } }先寫這麽多,慢慢補充吧
C#窗口閃爍問題解決