首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# Graphics 繪圖:正確在 Paint 事件中動態改變畫筆顏色

     編輯:程式設計綜合問答

錯誤做法

在按鈕點擊事件中直接呼叫 `Graphics.DrawEllipse` 並 `Thread.Sleep` 動畫,會導致:視窗遮擋/最小化後圖形消失、UI 凍結、重繪邏輯混亂。

正確架構:Paint 事件驅動繪圖

// 表單層級欄位
private List circles = new List();
private Random rand = new Random();

// 圓形資料類別
class Circle {
    public int X, Y, R;
    public Color PenColor;
    public Circle(int x, int y, int r, Color c) { X=x; Y=y; R=r; PenColor=c; }
}

// Paint 事件:所有繪圖邏輯集中於此
private void Form1_Paint(object sender, PaintEventArgs e) {
    foreach (var c in circles) {
        using (Pen pen = new Pen(c.PenColor, 2)) {
            e.Graphics.DrawEllipse(pen, c.X, c.Y, c.R, c.R);
        }
    }
}

// 按鈕點擊:只修改資料並觸發重繪
private void btnAddCircle_Click(object sender, EventArgs e) {
    Color randomColor = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));
    circles.Add(new Circle(50, 50 + circles.Count * 30, 20, randomColor));
    this.Invalidate(); // 標記需重繪,觸發 Paint 事件
}

// 動畫效果:使用 Timer 而非 Sleep
private void btnAnimate_Click(object sender, EventArgs e) {
    Timer timer = new Timer { Interval = 50 };
    int step = 0;
    timer.Tick += (s, args) => {
        if (step++ > 20) { timer.Stop(); return; }
        circles[0].X += 5; // 移動第一個圓
        this.Invalidate();
    };
    timer.Start();
}

核心原則

  1. 所有繪圖在 Paint 事件中進行,由系統自動管理重繪時機。
  2. 資料與繪圖分離:資料模型保存幾何屬性與顏色,Paint 只負責讀取資料繪製。
  3. 動畫用 Timer/Task.Delay 更新資料後呼叫 `Invalidate()`,不可用 `Sleep` 阻塞 UI 執行緒。
  4. 筆刷、畫筆等 `IDisposable` 物件用 `using` 區塊釋放。

遵循此模式,即可實現流暢、穩定、可維護的自繪圖形與動畫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved