TCategoryPanelGroup 擁有兩個獨立的高度控制層級:
TCategoryPanelGroup,控制所有面板標題列的統一高度TCategoryPanel,控制單一面板展開時的內容區高度 (含標題)掌握這雙層機制,才能精準控制摺疊面板群的佈局行為。

uses ExtCtrls;
procedure TForm1.FormCreate(Sender: TObject);
begin
// 初始化面板高度 (展開狀態)
CategoryPanel1.Height := ClientHeight div 2;
CategoryPanel2.Height := CategoryPanel1.Height;
CategoryPanel3.Height := CategoryPanel1.Height;
CategoryPanel1.Caption := 'CPanel1';
CategoryPanel2.Caption := 'CPanel2';
CategoryPanel3.Caption := 'CPanel3';
// 視覺設定
CategoryPanelGroup1.GradientBaseColor := clYellow;
CategoryPanelGroup1.GradientColor := clRed;
CategoryPanel1.Color := clWhite;
Button1.Caption := 'HeaderHeight +';
Button2.Caption := 'HeaderHeight -';
Button3.Caption := 'Panel1.Height +';
Button4.Caption := 'Panel1.Height -';
end;
procedure TForm1.Button1Click(Sender: TObject); // 群組標題高度 +
begin
CategoryPanelGroup1.HeaderHeight := CategoryPanelGroup1.HeaderHeight + 2;
end;
procedure TForm1.Button2Click(Sender: TObject); // 群組標題高度 -
begin
CategoryPanelGroup1.HeaderHeight := CategoryPanelGroup1.HeaderHeight - 2;
end;
procedure TForm1.Button3Click(Sender: TObject); // 單一面板高度 +
begin
CategoryPanel1.Height := CategoryPanel1.Height + 10;
end;
procedure TForm1.Button4Click(Sender: TObject); // 單一面板高度 -
begin
CategoryPanel1.Height := CategoryPanel1.Height - 10;
end;
| 特性 | 說明 |
|---|---|
| 影響範圍 | 群組內所有面板的標題列 |
| 最小值 | 通常 ≥ 字型高度 + 邊距 (約 16-20px) |
| 動態調整 | 即時生效,所有面板標題同步變化 |
| 摺疊狀態 | 面板摺疊時,面板總高度 = HeaderHeight |
| 預設值 | 約 22px (視字型而定) |
| 特性 | 說明 |
|---|---|
| 影響範圍 | 僅該面板展開時的總高度 (含標題) |
| 內容區高度 | 實際可用高度 = Height - HeaderHeight |
| 摺疊時 | Height 屬性仍保留展開時的值,不隨摺疊改變 |
| 獨立性 | 各面板 Height 互不影響 |
| 最小值 | ≥ HeaderHeight (否則內容區無空間) |
procedure TForm1.AutoFitPanelContent(Panel: TCategoryPanel; ContentControl: TControl; Padding: Integer = 10);
var
requiredHeight: Integer;
begin
// 計算內容控制項所需高度
requiredHeight := ContentControl.Top + ContentControl.Height + Padding;
// 面板總高度 = 標題高度 + 內容高度
Panel.Height := CategoryPanelGroup1.HeaderHeight + requiredHeight;
end;
// 使用範例:動態載入表單/框架到面板後呼叫
AutoFitPanelContent(CategoryPanel1, EmbeddedFrame1);
procedure TForm1.FormResize(Sender: TObject);
var
i: Integer;
availableHeight: Integer;
panelHeight: Integer;
begin
availableHeight := CategoryPanelGroup1.ClientHeight;
// 扣除所有標題高度
for i := 0 to CategoryPanelGroup1.Panels.Count - 1 do
Dec(availableHeight, CategoryPanelGroup1.HeaderHeight);
// 平均分配剩餘高度給展開的面板
panelHeight := availableHeight div CategoryPanelGroup1.Panels.Count;
for i := 0 to CategoryPanelGroup1.Panels.Count - 1 do
if not CategoryPanelGroup1.Panels[i].Collapsed then
CategoryPanelGroup1.Panels[i].Height := panelHeight + CategoryPanelGroup1.HeaderHeight;
end;
procedure TForm1.SetHeaderFontSize(Size: Integer);
begin
CategoryPanelGroup1.HeaderFont.Size := Size;
// 根據字型高度自動計算最小 HeaderHeight
CategoryPanelGroup1.HeaderHeight := Max(Size + 8, 22); // 8px 邊距緩衝
CategoryPanelGroup1.HeaderFont := CategoryPanelGroup1.HeaderFont; // 觸發重繪
end;
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 設定 Height 後面板不變大 | 面板處於摺疊狀態 | 先 Collapsed := False 再設 Height,或用 ExpandAll |
| HeaderHeight 設太小文字被切 | 小於字型渲染需求 | 設定 ≥ HeaderFont.Height 絕對值 + 邊距 |
| 動態調整後滾動條異常 | VertScrollBar.Tracking/Range 未更新 | 設定 VertScrollBar.Tracking := True,或呼叫 Realign |
| 面板重疊/消失 | Height < HeaderHeight 或負值 | 設定前檢查 Max(NewHeight, HeaderHeight + MinContentHeight) |
uses System.Threading;
procedure TForm1.AnimatePanelHeight(Panel: TCategoryPanel; TargetHeight: Integer; Duration: Cardinal = 300);
var
startHeight: Integer;
startTime: Cardinal;
task: ITask;
begin
startHeight := Panel.Height;
startTime := TThread.GetTickCount;
task := TTask.Run(procedure
var
elapsed: Cardinal;
progress: Double;
currentHeight: Integer;
begin
repeat
elapsed := TThread.GetTickCount - startTime;
progress := Min(elapsed / Duration, 1.0);
currentHeight := Round(startHeight + (TargetHeight - startHeight) * progress);
TThread.Synchronize(nil, procedure
begin
Panel.Height := currentHeight;
end);
Sleep(16); // ~60fps
until progress >= 1.0;
end);
end;
// 使用:點擊按鈕平滑展開/摺疊
AnimatePanelHeight(CategoryPanel1, 300);
TCategoryPanelGroup 的雙層高度控制 (HeaderHeight + Panel.Height) 提供了精細的佈局掌控力。理解群組統一標題高度與面板獨立內容高度的職責分離,配合動態計算、響應式重分配、動畫過渡等技巧,即能打造流暢、適應性強的摺疊面板介面。