public void RefreshSize(Graphics g) {
ArrayList cells = new ArrayList(); // 重用避免頻繁配置
Size viewSize = Size.Empty;
int leftCount = 0;
for (int col = 0; col < 1000; col++) { // 硬性上限 1000 欄
cells.Clear();
// 1. 收集第 col 欄的所有單元格
for (int row = 0; row < myDocument.Count; row++) {
CellRow r = myDocument[row];
if (col < r.Count) {
Cell cell = r[col];
cell.intLeft = leftCount; // 設定左邊界
cell.intTop = row * RowHeight; // 設定上邊界(固定行高)
cells.Add(cell);
}
}
if (cells.Count == 0) break; // 該欄無資料,結束
// 2. 計算該欄最大文字顯示寬度
int maxWidth = 40; // 最小寬度保護
foreach (Cell cell in cells) {
string txt = cell.Text;
if (txt != null && txt.Length > 0) {
SizeF sz = g.MeasureString(txt, Font, 1000, StringFormat.GenericDefault);
if (maxWidth < (int)sz.Width) maxWidth = (int)sz.Width;
}
}
maxWidth += 10; // 左右各 5 像素留白
// 3. 將計算出的欄寬套用至該欄所有單元格
foreach (Cell 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(); // 要求重繪
}
}
ArrayList 重用減少 GC 壓力。呼叫端以 using (Graphics g = this.CreateGraphics()) { RefreshSize(g); } 取得螢幕相容繪圖介面供 MeasureString 使用。**切記不可 new Graphics()**。
設定此屬性後,UserControl 內建邏輯自動:
開發者只需在文檔尺寸變更時更新此屬性,捲動行為全自動。