public void RefreshSize(Graphics g) {
var cells = new ArrayList();
Size viewSize = Size.Empty;
int leftCount = 0;
for (int col = 0; col < 1000; col++) { // 最多 1000 欄
cells.Clear();
// 收集該欄所有列的單元格
for (int row = 0; row < myDocument.Count; row++) {
var r = myDocument[row];
if (col < r.Count) {
var cell = r[col];
cell.intLeft = leftCount;
cell.intTop = row * RowHeight;
cells.Add(cell);
}
}
if (cells.Count == 0) break; // 無更多欄位
// 計算該欄最大文字寬度
int maxWidth = 40; // 最小寬度
foreach (var cell in cells) if (!string.IsNullOrEmpty(cell.Text)) {
SizeF sz = g.MeasureString(cell.Text, Font, 1000, StringFormat.GenericDefault);
if (maxWidth < (int)sz.Width) maxWidth = (int)sz.Width;
}
maxWidth += 10; // 留白
// 套用欄寬並更新文檔總尺寸
foreach (var cell in cells) {
cell.intWidth = maxWidth;
cell.intHeight = RowHeight;
if (cell.Left + cell.Width > viewSize.Width) viewSize.Width = cell.Left + cell.Width;
if (cell.Top + cell.Height > viewSize.Height) viewSize.Height = cell.Top + cell.Height;
}
leftCount += maxWidth;
}
viewSize.Width += 10; viewSize.Height += 10; // 邊距
if (!AutoScrollMinSize.Equals(viewSize)) {
AutoScrollMinSize = viewSize; // 觸發捲動條自動顯示/隱藏
Invalidate();
}
}
CreateGraphics() 取得螢幕相容 Graphics 供 MeasureString 使用(不可 new Graphics())。AutoScrollMinSize:UserControl 內建自動捲動支援,設定此屬性即可自動管理捲動條顯示與大小變更響應。Invalidate() 通知重繪。見 RefreshSize 已預先計算好每個單元格的 Bounds,OnPaint 僅需遍歷繪製。
Cell/CellRow/CellDocument 純資料結構。RefreshSize 計算幾何資訊。OnPaint 純渲染邏輯。分層讓複雜度可控,也是圖形控件開發的標準範式。