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.A == 255:完全不透明。Color.A == 0:完全透明 → **繪製無意義,直接略過建立 Pen/Brush**。1~254:半透明,值越小越透明。此技巧避免建立無效 GDI 物件,並防止透明色導致的非預期混色。
InvalidateCell。