在 WinForm 的 Paint 繪圖事件中使用 Invalidate() 重繪時會一直閃爍,最基本的解決方式就是啟用雙緩衝
為什麼使用雙重緩衝就可以大幅減少閃爍呢?開啟雙重緩衝之後要畫到螢幕上的圖形會先被繪製到緩衝區上面,畫完後再貼上到實際顯示的介面上,這樣可以減少介面上繪製的時間,以達到減少閃爍。
再進階一點會使用
UserPaint 是讓控制項忽略視窗訊息 WM_ERASEBKGND 以減少閃爍
只要開啟 DoubleBuffer,官方建議也開啟 AllPaintingInWmPaint 和 UserPaint
另外如果有執行大面積的繪製,例如每次繪製前都會先將背景全部畫上白色,然後再畫上其他圖形。這樣的作法也可能會出現閃爍的情況,因為在快速的持續重繪中,使用者很有可能在某個瞬間會明顯的看到整個畫面都是白色,然後才出現其他圖形,雖然時間很短暫,但的確會讓使用者感覺到閃爍。
如果發生上述需要繪製「背景」的情況,最佳的作法是把「整個場景」畫完,再一次畫到畫布上。
參考資料:
ControlStyles
為什麼使用雙重緩衝就可以大幅減少閃爍呢?開啟雙重緩衝之後要畫到螢幕上的圖形會先被繪製到緩衝區上面,畫完後再貼上到實際顯示的介面上,這樣可以減少介面上繪製的時間,以達到減少閃爍。
this.DoubleBuffered = true;
再進階一點會使用
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
UserPaint 是讓控制項忽略視窗訊息 WM_ERASEBKGND 以減少閃爍
只要開啟 DoubleBuffer,官方建議也開啟 AllPaintingInWmPaint 和 UserPaint
另外如果有執行大面積的繪製,例如每次繪製前都會先將背景全部畫上白色,然後再畫上其他圖形。這樣的作法也可能會出現閃爍的情況,因為在快速的持續重繪中,使用者很有可能在某個瞬間會明顯的看到整個畫面都是白色,然後才出現其他圖形,雖然時間很短暫,但的確會讓使用者感覺到閃爍。
如果發生上述需要繪製「背景」的情況,最佳的作法是把「整個場景」畫完,再一次畫到畫布上。
private void Windrose_Paint(object? sender, PaintEventArgs e)
{
// 先畫到圖片上
var bitmap = new Bitmap(this.Width, this.Height);
var graphics = Graphics.FromImage(bitmap);
// 背景塗滿白色
graphics.FillRectangle(Brushes.White, 0, 0, this.Width, this.Height);
// 畫線
graphics.DrawLine(Pens.Black, new Point(0,0),new Point(100,100));
// 畫其他所有圖案
// 再一次畫到介面上
e.Graphics.DrawImage(bitmap, 0, 0);
}
參考資料:
ControlStyles
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com