適用場景:容器控件動態載入多個子控件,且容器狀態切換(如 Normal 切換至 Maximized)時,若無特殊處理,子控件會劇烈閃爍。
Windows 在狀態切換時需「擦除」背景並重繪,效能不佳的機器上尤為明顯,子控件越多越嚴重。
ListView.BeginUpdate 暫停繪製,EndUpdate 恢復。內部實作關鍵在於發送 WM_SETREDRAW (0x0B) 訊息:
internal void BeginUpdateInternal() {
if (this.IsHandleCreated) {
if (this.updateCount == 0) this.SendMessage(11, 0, 0); // WM_SETREDRAW = 0x0B
this.updateCount++;
}
}
internal bool EndUpdateInternal(bool invalidate) {
if (this.updateCount <= 0) return false;
this.updateCount--;
if (this.updateCount == 0) {
this.SendMessage(11, -1, 0); // 恢復重繪
if (invalidate) this.Invalidate();
}
return true;
}
原理:對子控件操作在「凍結」狀態下進行,所有準備就緒後一次性重繪,避免中間狀態閃爍。可將此模式套用至自訂容器控件。