Refresh() 會先以背景色清空整個控件,再繪製圖像。即使使用雙緩衝,中間仍會產生一個「空白幀」,高頻重繪時即產生閃爍。
Graphics g = this.CreateGraphics()(不可用 PaintEventArgs 的 g)。Invalidate(new Rectangle(0, 0, 1, 1))。OnPaint 中直接繪製雙緩衝位圖。Invalidate(new Rectangle(0,0,1,1)) 會觸發 Paint 事件,但不會清空背景(因區域極小),避免空白幀產生,閃爍徹底消失。
核心代碼:
Bitmap buffer = new Bitmap(this.Width, this.Height);
using (Graphics g = Graphics.FromImage(buffer))
{
// 繪製所有圖形至 buffer
}
this.Invalidate(new Rectangle(0, 0, 1, 1)); // 觸發 Paint 不清背景
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(buffer, 0, 0);
}
原理重於技巧,理解機制才能舉一反三。