C# WinForm 有效解決 Paint 閃爍問題的幾種方式

在 WinForm 的 Paint 繪圖事件中使用 Invalidate() 重繪時會一直閃爍,最基本的解決方式就是啟用雙緩衝

為什麼使用雙重緩衝就可以大幅減少閃爍呢?開啟雙重緩衝之後要畫到螢幕上的圖形會先被繪製到緩衝區上面,畫完後再貼上到實際顯示的介面上,這樣可以減少介面上繪製的時間,以達到減少閃爍。
    
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

留言