首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 圖形中級篇:網格繪製優化與 Color 透明度判斷(第六講·中)

     編輯:關於C語言

OnPaint:剪切矩形 + 座標轉換 + 逐格繪製

protected override void OnPaint(PaintEventArgs e) {
    base.OnPaint(e);

    // 1. 取得剪切矩形並轉為視圖座標
    Rectangle clipRect = e.ClipRectangle;
    clipRect.Offset(-AutoScrollPosition.X, -AutoScrollPosition.Y);

    // 2. 整體座標系平移(折射修正)
    e.Graphics.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y);

    // 3. 準備畫筆/畫刷(透明度為 0 時不建立物件)
    Pen gridPen = (intGridColor.A != 0) ? new Pen(intGridColor) : null;
    SolidBrush gridBrush = (intGridBackColor.A != 0) ? new SolidBrush(intGridBackColor) : null;
    SolidBrush textBrush = new SolidBrush(ForeColor);

    // 4. 文字格式:靠左、垂直置中、不換行
    StringFormat fmt = new StringFormat {
        Alignment = StringAlignment.Near,
        LineAlignment = StringAlignment.Center,
        FormatFlags = StringFormatFlags.NoWrap
    };

    try {
        foreach (var row in myDocument)
        foreach (var cell in row) {
            Rectangle bounds = cell.Bounds;

            // 剪切優化:不相交直接跳過
            if (!clipRect.IntersectsWith(bounds)) continue;

            // 背景:選取用系統高亮,否則用網格背景色
            if (cell.Selected)
                e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds);
            else if (gridBrush != null)
                e.Graphics.FillRectangle(gridBrush, bounds);

            // 邊框
            if (gridPen != null)
                e.Graphics.DrawRectangle(gridPen, bounds);

            // 文字:選取用高亮文字色
            if (cell.Text != null)
                e.Graphics.DrawString(cell.Text, Font,
                    cell.Selected ? SystemBrushes.HighlightText : textBrush,
                    new RectangleF(cell.Left, cell.Top, cell.Width, cell.Height), fmt);
        }
    }
    finally {
        // 手動釋放非 using 管理的物件
        gridPen?.Dispose();
        gridBrush?.Dispose();
        textBrush.Dispose();
        fmt.Dispose();
    }
}

Color 結構透明度(Alpha)判斷技巧

  • Color.A == 255:完全不透明。
  • Color.A == 0:完全透明 → **繪製無意義,直接略過建立 Pen/Brush**。
  • 1~254:半透明,值越小越透明。

此技巧避免建立無效 GDI 物件,並防止透明色導致的非預期混色。

效能三板斧

  1. ClipRectangle 過濾:只繪製可見區域。
  2. TranslateTransform 整體平移:避免每個單元格單獨 Offset 運算。
  3. 差異化失效:滑鼠事件中僅當選取狀態真正改變時呼叫 InvalidateCell。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved