Delphi TStringGrid控件学习笔记

一.设置文本属性.

注意到,在CELL这个方法中,与我们常用的VBA参数的写法是相反的.

DELPHI先列后行:  property Cells[ACol, ARow: Integer]: string read GetCells write SetCells; 

VBA先行后列: CELLS(ROW,COL)

image

 

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Cells[0,0]:='序号';
  StringGrid1.Cells[1,0]:='操作';
  StringGrid1.Cells[2,0]:='结果';
  StringGrid1.Cells[0,1]:='1';
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: LongInt;
  Rect: TRect; State: TGridDrawState);
var
  S: string;
  DrawFlags: Integer;
  LGrid: TStringGrid;
begin
  LGrid := TStringGrid(Sender);

  // 1. 处理标题行 (FixedRows, 这里假定是第0行)
  if (ARow = 0) then
  begin
    // 设置标题行单元格背景色
    LGrid.Canvas.Brush.Color := clBtnFace; // 使用标准按钮面部颜色作为标题背景
    LGrid.Canvas.FillRect(Rect); // 用画刷颜色填充单元格矩形区域

    // 设置标题字体为加粗
    LGrid.Canvas.Font.Style := [fsBold];
    // 设置文本颜色(可选)
    // LGrid.Canvas.Font.Color := clWindowText;

    S := LGrid.Cells[ACol, ARow]; // 获取单元格文本
    DrawFlags := DT_VCENTER or DT_SINGLELINE or DT_CENTER; // 垂直居中、单行、水平居中

    // 使用 DrawText 函数绘制文本,实现居中
    DrawText(LGrid.Canvas.Handle, PChar(S), Length(S), Rect, DrawFlags);
  end
  else
  begin
    // 2. 处理数据行(非标题行)的默认绘制(可选)
    // 如果你想保持数据行的默认绘制方式,或者也想自定义数据行,可以在这里处理
    LGrid.Canvas.Brush.Color := clWindow; // 默认窗口背景色
    LGrid.Canvas.FillRect(Rect);
    LGrid.Canvas.Font.Style := []; // 常规字体
    // 使用 TextRect 绘制数据行文本(默认左对齐)
    LGrid.Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, LGrid.Cells[ACol, ARow]);

    // 或者,如果你希望数据行也居中,可以类似标题行那样使用 DrawText
    // DrawFlags := DT_VCENTER or DT_SINGLELINE or DT_CENTER;
    // DrawText(LGrid.Canvas.Handle, PChar(LGrid.Cells[ACol, ARow]), -1, Rect, DrawFlags);
  end;
end;

二.表格右键菜单设置.

image

 

这里提醒一下大家,菜单在创建时,其name是随机的,比如K1,N1,M1等等,请务必修改为具有实际意义的名称,方便阅读与引用.

在引用菜单时,请直接使用菜单的name,不要使用Item属性,比如下面这种写法非常不推荐使用.

PopupMenu1.Items[0].Visible := False; // '删除行'

image

 

然后设置表格的OnMouseDown事件

procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ACol, ARow: Integer;
begin
  if Button = mbRight then    // 检查是否是右键点击
  begin
    StringGrid1.MouseToCell(X, Y, ACol, ARow);   // 将鼠标坐标转换为单元格坐标.一个常用的,强大而有越的方法
    // 使用菜单项的 Name 来引用,这样更清晰可靠
    mnuDeleteRow.Visible := (ACol = 0) and (ARow > 0);   // 在第一列(非标题行)
    mnuDeleteCol.Visible := (ARow = 0) and (ACol > 0);   // 在第一行(非标题列)
    mnuClear.Visible     := (ARow > 0) and (ACol > 0);   // 在数据区域
  end;
end;

 

test

三.向表格中填充数据.

//如果数据量比较小的话,可以 封装一个公共过程.有几个列就有几个参数
procedure TForm1.AddRowToGrid(Operation, Result: string);
var
  NewRow: Integer;
begin
  // 添加新行(在现有行数基础上+1)
  NewRow := StringGrid1.RowCount;
  StringGrid1.RowCount := StringGrid1.RowCount + 1;

  // 填充新行数据
  StringGrid1.Cells[0, NewRow] := IntToStr(NewRow); // 自动编号
  StringGrid1.Cells[1, NewRow] := Operation;
  StringGrid1.Cells[2, NewRow] := Result;
end;

// 使用示例
procedure TForm1.Button1Click(Sender: TObject);
begin
  AddRowToGrid('测试操作', '通过');
  AddRowToGrid('验证数据', '失败');
  AddRowToGrid('生成报告', '成功');
end;

//如果数据量比较大且列数较多的话,把参数改成数组,批量添加多行数据,性能最优
procedure TForm1.AddMultipleRows(const Rows: TArray<TArray<string>>);
var
  StartRow, i, j: Integer;
begin
  if Length(Rows) = 0 then Exit;

  StringGrid1.BeginUpdate;
  try
    StartRow := StringGrid1.RowCount;
    StringGrid1.RowCount := StartRow + Length(Rows);

    for i := 0 to High(Rows) do
    begin
      // 自动序号
      StringGrid1.Cells[0, StartRow + i] := IntToStr(StartRow + i);
      
      // 填充数据列
      for j := 0 to High(Rows[i]) do
      begin
        if j < StringGrid1.ColCount - 1 then // -1 因为序号占一列
          StringGrid1.Cells[j + 1, StartRow + i] := Rows[i][j];
      end;
    end;
  finally
    StringGrid1.EndUpdate;
  end;
end;

// 使用示例
procedure TForm1.Button1Click(Sender: TObject);
var
  Data: TArray<TArray<string>>;
begin
  SetLength(Data, 3);    //假设要写入3行数据
  Data[0] := ['打开文件', '成功',...];   //注意这里...省略了多余的字段,请按实际修改
  Data[1] := ['读取数据', '失败', ...];
  Data[2] := ['处理信息', '进行中', ...];
  
  AddMultipleRows(Data);    //写入数据
end;    

 四.向表格中载入EXCEL文件中的数据.

1.确保查询能正确获取到数据

image

2.使用"可视化绑定"功能,连接StringGrid与FDQuery

test

 

posted @ 2025-09-11 04:10  一曲轻扬  阅读(52)  评论(0)    收藏  举报