1. 程式人生 > >C#窗口閃爍問題解決

C#窗口閃爍問題解決

int soft apple alt CP 消息 第一個 ras 視覺

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#窗口閃爍問題解決