自從米格的仁兄向我推薦C#之後,偶就誤入歧途的漸漸脫離了Java陣營。最近在寫工具的時候,忽然發現了一個老生常談的閃爍問題,要知道這樣的問題在Java Swing裡只要把DoubleBuffer設置為true基本上是不會發生的,但在C#上卻怎麼也搞不定,竟然連雙緩沖都有問題,GDI+不會這麼脆弱吧。
偶再一次被微軟的花頭給戲弄了,無奈只好踏上了漫漫搜索之路,也不知道搜了多少帖子,找了多少資料,基本上都是無功而返,更可氣的是網上有些資料還騙人,偶試了試基本上都不行的,該閃的照樣閃的歡。有些方法像髒矩陣一樣要Invalide部分更新區域,偶嫌他麻煩,幸好偶找到了一篇文章,講閃爍原理的,雖然偶過去自認為了解閃爍原理,比如什麼刷新周期,顯存之類的,不過偶還是耐著性子看了一遍,收獲頗豐,看來孔夫子的溫故而知新頗有道理!
於是偶按照原理自己改起了代碼,沒想到還真讓我給解決了。C#控件之所以會閃爍,是因為Refresh會把整個控件給清成背景色,然後再把圖像繪制上去,就算先把所有待畫的圖像繪制到緩沖上,然後再Render到控件上,因為清屏時的顏色,相當於中間插了一空白幀,當刷新過快時也是會有閃爍的。
偶的做法是:
1.每幀控件創建一個Graphics,記得一定是CreateGraphics而不是通過Paint函數的那個參數e獲得。
2.把待繪制的圖像繪制到緩沖上,緩沖大小為控件大小。
3.刷新的時候調用Invalidate(new Rectangle(0, 0, 1, 1));
4.在Paint函數繪制緩沖,搞定!
哈哈,相信大家看了都會了解,Invalidate(new Rectangle(0, 0, 1, 1));相當於調用Paint函數,但卻不重繪控件,這樣中間那個空白幀就沒有了,閃爍當然就消失啦!
原理很重要啊很重要!