// (* 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;
{ //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;