在 Windows Forms 開發中,手動觸發控制項重繪時常會用到 Invalidate、Update、Refresh 三個方法。它們雖然都能讓畫面更新,但運作機制與適用情境截然不同。
| 方法 | 行為 | 同步/非同步 | 適用情境 |
|---|---|---|---|
Invalidate() |
將指定區域標記為「需重繪」,發送 WM_PAINT 訊息到訊息佇列,等待下一次訊息迴圈處理。 |
非同步 | 大多數情況,效能最佳,避免重複重繪。 |
Update() |
立即處理目前佇列中所有的 WM_PAINT 訊息,強制同步重繪。 |
同步 | 需要立即看到畫面更新(如長時間運算中顯示進度)。 |
Refresh() |
相當於 Invalidate() + Update(),先標記再強制同步重繪,且會遞迴處理子控制項。 |
同步 | 必須確保控制項及其子項立即完整重繪。 |
Invalidate() 無參數版本內部呼叫 Invalidate(false),表示不重繪子控制項。若傳入 true,則會連同子控制項一起標記重繪。
核心邏輯(簡化版):
public void Invalidate(bool invalidateChildren)
{
if (this.IsHandleCreated)
{
if (invalidateChildren)
{
// 使用 RedrawWindow 連同子視窗一起重繪
SafeNativeMethods.RedrawWindow(..., 133); // RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE
}
else
{
// 僅重繪自身
SafeNativeMethods.InvalidateRect(..., (controlStyle & ControlStyles.Opaque) != ControlStyles.Opaque);
}
this.NotifyInvalidate(this.ClientRectangle);
}
}
Invalidate(),讓系統在適當時機批次處理重繪,效能最好。Update() 或 Refresh()。Refresh() 會導致 UI 執行緒阻塞,造成介面卡頓。