首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Delphi TAdvStringGrid 動態配置完整實戰:屬性陣列驅動 Cells 設定

     編輯:Oracle 資料庫相關知識

核心設計理念

將 Grid 的所有欄位屬性(顯示/編輯/對齊/顏色/寬度/標題/資料來源等)集中定義於常數陣列中,執行期透過事件處理程式動態套用。修改介面只需調整陣列內容,無需動到邏輯代碼,極大提升維護性與可移植性。

前置準備

  1. 放置 TAdvStringGrid,命名 strGrid1
  2. 設定屬性:Options.goEditing = True、EnableGraphics = True
  3. 表單命名 Form1 或自行替換代碼中的名稱
  4. 關聯事件:FormCreate、FormShow、strGrid1CanEditCell、strGrid1GetAlignment、strGrid1GetCellColor、strGrid1GetEditorType

常數定義區

const
  cUnit_ID = 'ENMA0101';
  cColQty1 = 8;  -- 欄位數

  -- 欄位屬性陣列 [欄位, 屬性]
  -- 屬性索引:0顯示 1編輯 2必輸 3類型 4對齊 5顏色 6寬度 7標題 8是否讀DB 9資料表 10欄位名 11長度 12文字檔讀取 13位置
  cColProp1: array[0..cColQty1-1] of array[0..13] of string = (
    ('Y','N','N','E','R','clBtnFace','25','NO.','N','','','0','N','0'),      -- 0: 序號
    ('Y','N','N','E','L','clInfoBk','150','Part No','Y','POJBSUB','PART_NO','30','Y','2'),  -- 1
    ('Y','Y','N','E','R','clWindow','60','Qty','Y','POJBSUB','ORDER_QUANTITY','9','Y','3'),   -- 2
    ('Y','N','N','E','C','clMoneyGreen','40','U/M','Y','POJBSUB','UNIT_OF_MEASURE','2','Y','4'), -- 3
    ('Y','Y','N','C','C','clWindow','60','Dept','Y','POJBSUB','DELIVERY_TO_DEPT','3','Y','5'), -- 4
    ('Y','Y','N','C','C','clWindow','50','Grp','Y','POJBSUB','GROUP_A','3','Y','7'),           -- 5
    ('Y','N','N','E','L','clSkyBlue','160','Part Name','Y','POJBSUB','PART_NAME_C','70','Y','8'), -- 6
    ('Y','Y','N','M','L','clWindow','50','DF','Y','POJBSUB','VENDOR_NO','5','Y','6')            -- 7
  );

  -- 欄位索引常數,便於程式碼引用
  cC1NO = 0; cC1PART_NO = 1; cC1ORDER_QUANTITY = 2; cC1UNIT_OF_MEASURE = 3;
  cC1DELIVERY_TO_DEPT = 4; cC1GROUP_A = 5; cC1PART_NAME_C = 6; cC1Data_Flag = 7;

核心事件處理程式

FormCreate - 初始化 CheckBox

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  strGrid1.RowCount := 1000;  -- 預留最大行數
  for i := 1 to strGrid1.RowCount - 1 do begin
    strGrid1.AddCheckBox(4, i, False, False);  -- 第 4 欄 CheckBox
    strGrid1.AddCheckBox(5, i, False, False);  -- 第 5 欄 CheckBox
  end;
end;

prStgInitialize1 - Grid 結構初始化

procedure TForm1.prStgInitialize1;
var I: Integer;
begin
  strGrid1.RowCount := 2;      -- 1 標題列 + 1 資料列
  strGrid1.ColCount := cColQty1;
  strGrid1.FixedRows := 1;
  strGrid1.FixedCols := 1;

  for I := 0 to cColQty1 - 1 do begin
    strGrid1.Cells[I, 0] := cColProp1[I, 7];  -- 標題
    if cColProp1[I, 0] = 'Y' then
      strGrid1.ColWidths[I] := StrToInt(cColProp1[I, 6])  -- 寬度
    else
      strGrid1.ColWidths[I] := 0;  -- 隱藏欄位
  end;
end;

strGrid1CanEditCell - 控制儲存格可編輯性

procedure TForm1.strGrid1CanEditCell(Sender: TObject; ARow, ACol: Integer; var CanEdit: Boolean);
var I: Integer;
begin
  if ARow = 0 then begin CanEdit := False; Exit; end;  -- 標題列不可編輯
  
  for I := 0 to cColQty1 - 1 do
    if ACol = I then begin
      CanEdit := (cColProp1[I, 1] = 'Y');
      Break;
    end;
  
  -- 進階:根據 Data_Flag 欄位動態控制整列編輯權限
  { if (strGrid1.Cells[cC1Data_Flag, ARow] = '') or (strGrid1.Cells[cC1Data_Flag, ARow] = 'C') then
      CanEdit := False; }
end;

strGrid1GetAlignment - 動態對齊

procedure TForm1.strGrid1GetAlignment(Sender: TObject; ARow, ACol: Integer; var AAlignment: TAlignment);
var I: Integer;
begin
  if ARow = 0 then AAlignment := taCenter
  else begin
    for I := 0 to cColQty1 - 1 do
      if ACol = I then begin
        case cColProp1[I, 4] of
          'C': AAlignment := taCenter;
          'L': AAlignment := taLeftJustify;
          'R': AAlignment := taRightJustify;
        end;
        Break;
      end;
  end;
end;

strGrid1GetCellColor - 動態顏色

procedure TForm1.strGrid1GetCellColor(Sender: TObject; ARow, ACol: Integer; 
  AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
var I: Integer;
begin
  if ARow = 0 then
    ABrush.Color := clBtnFace
  else begin
    for I := 0 to cColQty1 - 1 do
      if ACol = I then begin
        ABrush.Color := StringToColor(cColProp1[I, 5]);
        Break;
      end;
  end;
end;

strGrid1GetEditorType - 下拉式編輯器

procedure TForm1.strGrid1GetEditorType(Sender: TObject; ACol, ARow: Integer; var AEditor: TEditorType);
var I: Integer;
begin
  for I := 0 to cColQty1 - 1 do
    if ACol = I then begin
      if cColProp1[I, 3] = 'M' then begin  -- 'M' = ComboBox
        AEditor := edComboEdit;
        strGrid1.ClearComboString;
        strGrid1.AddComboString('Y : 同意');
        strGrid1.AddComboString('N : 拒絕');
      end;
      Break;
    end;
end;

Excel 輔助工具

提供 動態 Cells 設定工具表,可視化編輯欄位屬性並自動生成 Pascal 常數陣列代碼,避免手工修改大型陣列易出錯。

擴展建議

  • 將屬性陣列外部化為 INI/JSON/XML,實現真正的零代碼配置
  • 整合資料庫讀寫邏輯於 prRefresh、prClear 中
  • 善用 Tag 屬性儲存額外業務資料
  • 大量資料時啟用 BeginUpdate/EndUpdate 減少重繪
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved