TCategoryPanelGroup 是 Delphi 2009 強化的可摺疊面板容器,支援分組管理多個 TCategoryPanel。本文從建立流程、核心屬性/方法到實戰程式碼,完整解析入門必備知識。

TCategoryPanelGroup 到表單Caption 屬性 (如 'CPanel1'、'CPanel2'、'CPanel3')Height 適應內容| 屬性/方法 | 所屬 | 功能 | 備註 |
|---|---|---|---|
ChevronAlignment | Group | 摺疊箭號水平位置 (左/中/右) | 搭配 HeaderAlignment 使用 |
CollapseAll | Group | 摺疊群組內所有面板 | 方法,無參數 |
ExpandAll | Group | 展開群組內所有面板 | 方法,無參數 |
Collapsed | Panel | 單一面板摺疊狀態 (True/False) | 屬性,可讀寫 |
Height | Panel | 面板展開時總高度 (含標題) | 摺疊時保留此值 |
uses ExtCtrls, TypInfo;
const
BoolArr: array[Boolean] of string = ('關閉 CPanel1', '展開 CPanel1');
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
// 初始化面板高度
CategoryPanel1.Height := ClientHeight div 2;
CategoryPanel2.Height := CategoryPanel1.Height;
CategoryPanel3.Height := CategoryPanel1.Height;
CategoryPanel1.Caption := 'CPanel1';
CategoryPanel2.Caption := 'CPanel2';
CategoryPanel3.Caption := 'CPanel3';
// 統一按鈕事件
Button1.Tag := 1; // 全部關閉
Button2.Tag := 2; // 全部展開
Button3.Tag := 3; // 切換 CPanel1
Button2.OnClick := Button1.OnClick;
Button3.OnClick := Button1.OnClick;
Button1.Caption := '全部關閉';
Button2.Caption := '全部展開';
Button2.Click; // 預設展開所有
// ChevronAlignment RadioGroup
RadioGroup1.Caption := 'ChevronAlignment';
for i := 0 to 2 do
RadioGroup1.Items.Add(GetEnumName(TypeInfo(TAlignment), i));
RadioGroup1.ItemIndex := 0;
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
CategoryPanelGroup1.ChevronAlignment := TAlignment(RadioGroup1.ItemIndex);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
case TButton(Sender).Tag of
1: CategoryPanelGroup1.CollapseAll; // 群組方法:全部摺疊
2: CategoryPanelGroup1.ExpandAll; // 群組方法:全部展開
3: CategoryPanel1.Collapsed := not CategoryPanel1.Collapsed; // 單一面板屬性切換
end;
// 更新切換按鈕文字
Button3.Caption := BoolArr[CategoryPanel1.Collapsed];
end;
| 值 | 常數 | 視覺位置 | 搭配建議 |
|---|---|---|---|
| 0 | taLeftJustify | 標題最左側 | HeaderAlignment=taLeftJustify (標準) |
| 1 | taCenter | 標題置中 | 特殊設計、極簡風格 |
| 2 | taRightJustify | 標題最右側 | HeaderAlignment=taRightJustify (RTL) |
Collapsed := True/FalseOnCollapse/OnExpand 事件VertScrollBar.Range)
// 切換摺疊狀態
CategoryPanel1.Collapsed := not CategoryPanel1.Collapsed;
// 事件回應
procedure TForm1.CategoryPanel1Collapse(Sender: TObject);
begin
// 面板剛摺疊時執行
// 可釋放面板內重資源控制項、暫停計時器等
end;
procedure TForm1.CategoryPanel1Expand(Sender: TObject);
begin
// 面板剛展開時執行
// 可重建資源、恢復計時器、載入資料
end;
uses IniFiles;
procedure TForm1.SavePanelStates(Ini: TIniFile);
var i: Integer;
begin
for i := 0 to CategoryPanelGroup1.Panels.Count - 1 do
Ini.WriteBool('Panels', 'Panel' + IntToStr(i) + '_Collapsed',
CategoryPanelGroup1.Panels[i].Collapsed);
end;
procedure TForm1.LoadPanelStates(Ini: TIniFile);
var i: Integer;
begin
for i := 0 to CategoryPanelGroup1.Panels.Count - 1 do
CategoryPanelGroup1.Panels[i].Collapsed :=
Ini.ReadBool('Panels', 'Panel' + IntToStr(i) + '_Collapsed', False);
end;
procedure TForm1.CategoryPanelGroup1Expand(Sender: TObject);
var
Panel: TCategoryPanel;
i: Integer;
begin
Panel := Sender as TCategoryPanel;
// 摺疊其他面板
for i := 0 to CategoryPanelGroup1.Panels.Count - 1 do
if CategoryPanelGroup1.Panels[i] <> Panel then
CategoryPanelGroup1.Panels[i].Collapsed := True;
end;
// 需在設計期為每個面板設定 OnExpand 事件指向此處理程序
function TForm1.AddCategoryPanel(const Caption: string; Height: Integer): TCategoryPanel;
begin
Result := TCategoryPanel.Create(CategoryPanelGroup1);
Result.Parent := CategoryPanelGroup1;
Result.Caption := Caption;
Result.Height := Height;
Result.OnExpand := CategoryPanelGroup1Expand; // 掛載手風琴邏輯
Result.OnCollapse := CategoryPanel1Collapse;
end;
// 使用
var newPanel := AddCategoryPanel('動態面板', 200);
procedure TForm1.SetupPanelContent(Panel: TCategoryPanel; Content: TControl);
begin
Content.Parent := Panel;
Content.Align := alClient;
Content.Anchors := [akLeft, akTop, akRight, akBottom];
// 面板 Height 應 ≥ HeaderHeight + Content.Height + Padding
Panel.Height := CategoryPanelGroup1.HeaderHeight + Content.Height + 20;
end;
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 面板摺疊後無法展開 | Height 過小或為 0 | 確保設計期設定合理 Height (> HeaderHeight) |
| CollapseAll 後捲軸不更新 | VertScrollBar.Tracking 設定 | 設定 VertScrollBar.Tracking := True |
| 動態建立面板不顯示 | Parent 未正確指派 | Panel.Parent := CategoryPanelGroup1 |
| Chevron 點擊無反應 | 事件衝突或 Enabled=False | 檢查面板/群組 Enabled 屬性 |
| 標題文字與箭號重疊 | HeaderAlignment/ChevronAlignment 衝突 | 調整兩者一致或預留空間 |
用戶點擊 Chevron/標題
↓
Panel.Collapsed 切換 (True ↔ False)
↓
觸發 OnCollapse / OnExpand 事件
↓
面板高度變化: 展開=Height, 摺疊=HeaderHeight
↓
群組 VertScrollBar.Range 自動重算
↓
介面重繪完成
TCategoryPanelGroup 以 ChevronAlignment 控制視覺錨點,CollapseAll/ExpandAll 提供群組批量操作,Panel.Collapsed 實現單一面板精細控制。掌握建立流程、狀態切換邏輯、事件回應機制、持久化偏好、手風琴模式五大核心技巧,即能快速構建專業的分組摺疊介面。