DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tino0914
今日帖子: 30
在线用户: 14
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2019/5/19 9:32:22
标题:
Creating Columns by code in StringGrid VCL and FMX (FireMonkey) - my example! 浏览:2079
加入我的收藏
楼主: here my examples of StringGrid in VCL and FireMonkey (FMX) 
----------

StringGrid in VCL project:
----------
unit uFormMain;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,
  Vcl.Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    btnCreatingStringGridColumnsRow: TButton;
    btnComboBoxVisibleOrNot: TButton;
    Memo1: TMemo;
    btnDeleteMyCmbBoxOnStringGrid: TButton;
    procedure btnCreatingStringGridColumnsRowClick(Sender: TObject);
    procedure btnComboBoxVisibleOrNotClick(Sender: TObject);
    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure btnDeleteMyCmbBoxOnStringGridClick(Sender: TObject);
  published
    procedure MyCmbBoxCloseUp(Sender: TObject); // my event when close my choice in MyCmbBox
  private
    { Private declarations }
    procedure prcCreateMyCmbBox;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  lColInSelectCell: Integer;
  lRowInSelectCell: Integer;
  lMyCmbBox: TComboBox;

procedure TForm1.btnCreatingStringGridColumnsRowClick(Sender: TObject);
var
  i: Integer;
  lRectCell: TRect;
begin
  // StringGrid in VCL project
  //
  //
  StringGrid1.ColCount := 0; // removing...
  StringGrid1.RowCount := 0; // removing...
  //
  StringGrid1.ColCount := 3;
  StringGrid1.RowCount := 2;
  //
  for i := 0 to (StringGrid1.ColCount - 1) do
    StringGrid1.ColWidths[i] := 120; // Col #n, width
  //
  StringGrid1.ColWidths[0] := 150; // Col #1, width
  //
  StringGrid1.RowHeights[1] := 120; // Row #2 width
  // Cells[ col, row] := 'string-value'
  StringGrid1.Cells[0, 0] := 'string_value01';
  StringGrid1.Cells[1, 0] := 'string_value02';
  StringGrid1.Cells[2, 0] := 'string_value02';
  StringGrid1.Cells[0, 1] := 'string_value11';
  StringGrid1.Cells[1, 1] := 'string_value12';
  StringGrid1.Cells[2, 1] := 'string_value12';
  //
  // StringGrid1.Cols[1].Clear; // clean all Col #2
  //
  {
    lRectCell := StringGrid1.CellRect(lCol, lRow);
    //
    // position of TComboBox on StringGrid
    lRectCell.Top := lRectCell.Top + StringGrid1.Top;
    lRectCell.Left := lRectCell.Left + StringGrid1.Left;
    lRectCell.Bottom := lRectCell.Bottom + StringGrid1.Top;
    lRectCell.Right := lRectCell.Right + StringGrid1.Left;
    //
    lMyCmbBox.Top := lRectCell.Top + 1;
    lMyCmbBox.Left := lRectCell.Left + 1;
    lMyCmbBox.Height := (lRectCell.Bottom + 1) - lRectCell.Top;
  }
  // ---------- position end ----------
  //
  // lMyCmbBox.DropDownCount := 8;
  // lMyCmbBox.ItemHeight := 20;
  //
  // StringGrid1.Objects[0, 0] := lMyCmbBox;
  // StringGrid1.Cells[0, 0] := 'Added one ' + StringGrid1.Objects[0, 0].ToString;
  //

  //
  (*
    if StringGrid1.Objects[1, 1] <> nil then
    ShowMessage(StringGrid1.Objects[1, 1].ToString + ' Show #1 ');
    // Col, Row
    StringGrid1.Objects[1, 1] := lMyCmbBox;
    //
    //TComboBox(StringGrid1.Objects[1, 1]).Items.Add('Item1'); // add items in lMyCmbBox
    //TComboBox(StringGrid1.Objects[1, 1]).Items.Add('Item2'); // add items in lMyCmbBox
    //TComboBox(StringGrid1.Objects[1, 1]).Items.Add('Item3'); // add items in lMyCmbBox
    //TComboBox(StringGrid1.Objects[1, 1]).ItemIndex := 0;
    //
    // TObject(StringGrid1.Objects[1, 3]).Free;
    // you need release the object, because, StringList dont do it!
    // lMyCmbBox.Free; {or lMyCmbBox.DisposeOf and later lMyCmbBox := Nil; }
    //
    if StringGrid1.Objects[1, 1] <> nil then
    ShowMessage(StringGrid1.Objects[1, 1].ToString + ' Show #2 ');
    //
  *)
  //
  if (StringGrid1.Objects[0, 0] = nil) or (StringGrid1.Objects[0, 0].ClassType <> TComboBox) then
    prcCreateMyCmbBox;
  //
  Memo1.Lines.Clear;
  Memo1.Lines.Add(Format('StringGrid1.Cols[1].Text = %s', [StringGrid1.Cols[1].Text]));
  Memo1.Lines.Add(Format('StringGrid1.Rows[0].Text = %s', [StringGrid1.Rows[0].Text])); // all colunms in 'n' row
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Assigned(lMyCmbBox) then
    lMyCmbBox.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.ColWidths[0] := 150;
  //
  prcCreateMyCmbBox;
end;

procedure TForm1.MyCmbBoxCloseUp(Sender: TObject);
begin
  Memo1.Lines.Add('MyCmbBoxCloseUp --> ' + (Sender as TComboBox).Name + ' in OnCloseUp');
  //
  StringGrid1.Cells[lColInSelectCell, lRowInSelectCell] := (Sender as TComboBox).Items[(Sender as TComboBox).ItemIndex];
  (Sender as TComboBox).Visible := False;
  //
  // focus on StringGrid, not in Cells[ c, r] current! Just a hack!
  StringGrid1.SetFocus;
end;

procedure TForm1.prcCreateMyCmbBox;
begin
  Memo1.Lines.Clear;
  //
  Randomize;
  //
  lMyCmbBox := TComboBox.Create(nil); // NOTE: StringGrid1 dont destroy its objects!
  lMyCmbBox.Name := Format('MyCmbBox%d', [Random(10000000)]);
  lMyCmbBox.Parent := Form1; // need some parent to the object!
  //
  lMyCmbBox.Visible := False;
  //
  lMyCmbBox.OnCloseUp := MyCmbBoxCloseUp;
  //
  lMyCmbBox.Text := lMyCmbBox.Name;
  lMyCmbBox.Items.Add('Item1');
  lMyCmbBox.Items.Add('Item2');
  lMyCmbBox.Items.Add('Item3');
  lMyCmbBox.ItemIndex := 0;
  //
  StringGrid1.Objects[0, 0] := lMyCmbBox; // add this control to first cell on StringGrid
  //
  StringGrid1.Options := StringGrid1.Options - [TGridOption.goRangeSelect]; // dont select cell range
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
var
  lRectCell: TRect;
begin
  if (StringGrid1.Objects[ACol, ARow] <> nil) { and (StringGrid1.Objects[ACol, ARow].ClassType = TComboBox) } then
  begin
    Memo1.Lines.Add('StringGrid1SelectCell --> ' + TComboBox(StringGrid1.Objects[ACol, ARow]).Name + ' in OnSelectCell');
    //
    lColInSelectCell := ACol;
    lRowInSelectCell := ARow;
    //
    lRectCell := StringGrid1.CellRect(ACol, ARow);
    // position of TComboBox on StringGrid
    lRectCell.Top := lRectCell.Top + StringGrid1.Top;
    lRectCell.Left := lRectCell.Left + StringGrid1.Left;
    lRectCell.Bottom := lRectCell.Bottom + StringGrid1.Top;
    lRectCell.Right := lRectCell.Right + StringGrid1.Left;
    //
    TComboBox(StringGrid1.Objects[ACol, ARow]).Top := lRectCell.Top + 1;
    TComboBox(StringGrid1.Objects[ACol, ARow]).Left := lRectCell.Left + 1;
    TComboBox(StringGrid1.Objects[ACol, ARow]).Height := (lRectCell.Bottom + 1) - lRectCell.Top;
    //
    TComboBox(StringGrid1.Objects[ACol, ARow]).Visible := True;
    TComboBox(StringGrid1.Objects[ACol, ARow]).DroppedDown := True;
  end;
  //
end;

procedure TForm1.btnComboBoxVisibleOrNotClick(Sender: TObject);
begin
  if (StringGrid1.Objects[0, 0] <> nil) and (StringGrid1.Objects[0, 0] is TComboBox) then
    TComboBox(StringGrid1.Objects[0, 0]).Visible := not TComboBox(StringGrid1.Objects[0, 0]).Visible
  else
    ShowMessage('StringGrid1.Objects[0, 0]=nil or Is not a TComboBox');
end;

procedure TForm1.btnDeleteMyCmbBoxOnStringGridClick(Sender: TObject);
var
  lObjName: String;
begin
  if (StringGrid1.Objects[0, 0] <> nil) and (StringGrid1.Objects[0, 0].ClassType = TComboBox) then
  begin
    lObjName := TComboBox(StringGrid1.Objects[0, 0]).Name;
    //
    StringGrid1.Objects[0, 0] := nil;
    TComboBox(StringGrid1.Objects[0, 0]).Free;
    //
    StringGrid1.Cells[0, 0] := Format('%s deleted!', [lObjName]);
    //
    Memo1.Lines.Clear;
    Memo1.Lines.Add(Format('The obj [%s], was destroyed!', [lObjName]));
  end
  else
    ShowMessage('(StringGrid1.Objects[0, 0] = nil) or (StringGrid1.Objects[0, 0].ClassType <> TComboBox)');
end;

end.
----------

StringGrid in FMX project:
----------
unit uFormMain;

interface

uses
  System.SysUtils,
  System.Types,
  System.UITypes,
  System.Classes,
  System.Variants,
  FMX.Types,
  FMX.Controls,
  FMX.Forms,
  FMX.Graphics,
  FMX.Dialogs,
  // TStringGrid units added
  System.Rtti,
  FMX.Grid.Style,
  FMX.Controls.Presentation,
  FMX.ScrollBox,
  FMX.Grid,
  FMX.StdCtrls,
  FMX.Memo
  //
    ;

type
  TfrmMainUnit = class(TForm)
    StringGrid1: TStringGrid;
    btnAddTColumsInStringGrid: TButton;
    btnAddManyColumnsInStringGrid: TButton;
    btnDeleteColumnOnStringGrid: TButton;
    Memo1: TMemo;
    procedure btnAddTColumsInStringGridClick(Sender: TObject);
    procedure btnAddManyColumnsInStringGridClick(Sender: TObject);
    procedure btnDeleteColumnOnStringGridClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure prcLog(lClearMemo: Boolean = True);
  public
    { Public declarations }
  end;

var
  frmMainUnit: TfrmMainUnit;

implementation

{$R *.fmx}

{
  //added on project source - (Project->View Source)
  ReportMemoryLeaksOnShutdown := True; // if leak memory!
}
{
  // Options default:

  // StringGrid1.Options := [TGridOption.ColumnResize, TGridOption.Editing, TGridOption.ColumnMove, TGridOption.ColLines, TGridOption.RowLines, TGridOption.Tabs,
  // TGridOption.Header, TGridOption.HeaderClick, AutoDisplacement]
}
{
  if (StringGrid1.ColumnCount <= 0) or (StringGrid1.Columns[0].ChildrenCount <= 0) then
  begin
  ShowMessage('(StringGrid1.ColumnCount <= 0) or (StringGrid1.Columns[0].ChildrenCount <= 0');
  exit;
  end;
  //
  ShowMessage(StringGrid1.Columns[0].ChildrenCount.ToString);
  StringGrid1.Columns[0].DeleteChildren; // delete any children in this column
}
//
procedure TfrmMainUnit.btnAddTColumsInStringGridClick(Sender: TObject);
var
  // TColumns type pre-defined - start
  {
    Column1: TColumn;
    CheckColumn1: TCheckColumn;
    DateColumn1: TDateColumn;
    TimeColumn1: TTimeColumn;
    PopupColumn1: TPopupColumn;
    CurrencyColumn1: TCurrencyColumn;
    FloatColumn1: TFloatColumn;
    FloatColumn2: TFloatColumn;
    IntegerColumn1: TIntegerColumn;
    GlyphColumn1: TGlyphColumn;
  }
  StringColumn1: TStringColumn;
  //
begin
  //
  // btnAddTColumsInStringGrid.Enabled := False; // only add 1x for test
  //
  // creating the objects FMX to add in my TStringGrid FMX
  {
    Column1 := TColumn.Create(StringGrid1);
    CheckColumn1 := TCheckColumn.Create(StringGrid1);
    DateColumn1 := TDateColumn.Create(StringGrid1);
    TimeColumn1 := TTimeColumn.Create(StringGrid1);
    PopupColumn1 := TPopupColumn.Create(StringGrid1);
    CurrencyColumn1 := TCurrencyColumn.Create(StringGrid1);
    FloatColumn1 := TFloatColumn.Create(StringGrid1);
    FloatColumn1.ShowThousandSeparator := False;
    FloatColumn2 := TFloatColumn.Create(StringGrid1);
    FloatColumn2.ShowThousandSeparator := False;
    IntegerColumn1 := TIntegerColumn.Create(StringGrid1);
    GlyphColumn1 := TGlyphColumn.Create(StringGrid1);
  }
  StringColumn1 := TStringColumn.Create(StringGrid1);
  StringColumn1.Name := Format('obj_SG_ColName%d', [StringGrid1.ColumnCount + 1]);
  StringColumn1.Header := StringColumn1.Name;
  StringColumn1.Width := 110.0; // Single type
  StringColumn1.Parent := StringGrid1;
  //
  StringGrid1.AddObject(StringColumn1);
  StringGrid1.Cells[0, 0] := 'the value';
end;

procedure TfrmMainUnit.btnAddManyColumnsInStringGridClick(Sender: TObject);
var
  StringColumnS: Array [0 .. 3] of TStringColumn; // 4 columns!
  i: Integer;
  x: Integer;
  lRow: Integer;
  lCol: Integer;
  lRowMax: Integer;
begin
  //
  // btnAddManyColumnsInStringGrid.Enabled := False; // only add 1x for test
  //
  lRowMax := 3; // [3 rows X 4 cols]
  //
  for i := Low(StringColumnS) to High(StringColumnS) do
  begin
    StringColumnS[i] := TStringColumn.Create(StringGrid1);
    StringColumnS[i].Name := Format('obj_SG_ColName%d', [StringGrid1.ColumnCount + 1]);
    StringColumnS[i].Header := StringColumnS[i].Name;
    StringColumnS[i].Width := 110.0; // Single type
    StringColumnS[i].Parent := StringGrid1;
    //
    StringGrid1.AddObject(StringColumnS[i]);
    //
    for x := 0 to (lRowMax - 1) do
    begin
      lRow := x;
      lCol := (StringGrid1.ColumnCount - 1);
      // values to cells
      StringGrid1.Cells[lCol, lRow] := Format('[%d, %d]', [lCol, lRow]);
    end;
  end;
end;

procedure TfrmMainUnit.btnDeleteColumnOnStringGridClick(Sender: TObject);
var
  i: Integer;
  lObjColumnToDelete: TFmxObject;
  lString: String;
begin
  lString := '';
  //
  if (StringGrid1.ColumnCount <= 0) or (StringGrid1.Selected < 0) then
  begin
    prcLog();
    Memo1.Lines.Add('');
    Memo1.Lines.Add('(StringGrid1.ColumnCount <= 0) or (StringGrid1.Selected < 0)');
    exit;
  end;
  //
  // column selected or anyone valid!
  lObjColumnToDelete := StringGrid1.Columns[StringGrid1.Selected];
  //
  Memo1.Lines.Clear;
  Memo1.Lines.Add(Format('lObjColumnToDelete = %s', [lObjColumnToDelete.Name]));
  //
  // First, remove the column (ojb) from StringGrid (children list)!
  // BUT, it dont is released from memory! The obj exist, yet! IF you try create it again, booommm! Error!
  StringGrid1.RemoveObject(lObjColumnToDelete);
  //
  // NOW, kill the column (obj/component/class) from memory!
  // Then, you can create again, include with same name!
  // Else, you can have "memory leaks" when end your app!
  //
  lObjColumnToDelete.Free;
  //
  prcLog(False);
end;

procedure TfrmMainUnit.FormCreate(Sender: TObject);
begin
  prcLog;
end;

procedure TfrmMainUnit.prcLog(lClearMemo: Boolean = True);
var
  i: Integer;
  lString: String;
begin
  lString := '';
  //
  for i := 0 to (StringGrid1.ComponentCount - 1) do
  begin
    lString := Format('%s, %s, %s'#13#10, [lString, StringGrid1.Components[i].ClassName, StringGrid1.Components[i].Name]);
  end;
  //
  if lClearMemo then
    Memo1.Lines.Clear;
  //
  Memo1.Lines.Add(Format('Components in StringGrid'#13'%s', [lString]));
  Memo1.Lines.Add('');
  Memo1.Lines.Add(Format('# of Columns = %d', [StringGrid1.ColumnCount]));
end;

end.
----------

projects complete in Mega.nz (just 11KB)
https://mega.nz/#!XuQkHYaa!m1ujtphh3d6CLv7Usnyw6pvF5uj0iOBzOAY5WNUj-pM

按此在新窗口浏览图片

按此在新窗口浏览图片
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 zcbly (小菜) ▲▲▲▲△ -
普通会员
2019/5/19 9:58:51
1楼: 学习了!
----------------------------------------------
-
作者:
男 xlonger (xlonger) ★☆☆☆☆ -
普通会员
2019/5/19 15:33:42
2楼: 把控件嵌入到Grid里?
----------------------------------------------
我打的是酱油,而不是别的什么油。
我灌的是口水,而不是别的什么水。
我聊的折腾不是那个不折腾的折腾。
我说的阿娇不是那个邓玉娇的阿娇。
3个代表,6个为什么,9个肠胃炎。
D性强的领导干部都不喜欢热比娅。
我特别要讲的是,屁民网黄色论坛是我经常上网必选的 网站之一
作者:
男 andyliuxp (andyliuxp) ★☆☆☆☆ -
普通会员
2023/7/31 9:53:35
3楼: 感谢分享
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行750毫秒 RSS