Handling TButton as Custom Control in FNCDataGrid

I'm using FNCDataGrid with TButton as Custom Control.

for I := 1 to FNCDatGrid.RowCount - 1 do
 begin
   BT := TButton.Create(nil);
   BT.Caption := 'Delete';
   FNCDatGrid.Controls[7, I] := BT;
   FNCDatGrid.ManagedObjects[7, I] := BT;
 end;

After clicking TButton I'm deleting record and then I'm getting an Error: Control BT has no parent window. I don't know what could be the cause. Can you give me some hint, please.

Hi,

It could be possible that the button is still active while deleting the row where the button is on. Could you perhaps share some more details on this behavior? Do you call the dataset delete? From which event do you call the code? A possible workaround would be to handle this in a timer.

Hi,

Yes, indeed, Button is still active during deleting the row. I call the dataset delete. I use OnButtonClick to call the deleting procedure.

for I := 1 to FNCDatGrid.RowCount - 1 do
begin
  BT := TButton.Create(nil);
  BT.Caption := 'Delete';
  BT.OnClick := OnButtonClick;
  BT.Tag     := I;
  FNCDatGrid.Controls[7, I] := BT;
  FNCDatGrid.ManagedObjects[7, I] := BT;
end;
procedure OnButtonClick(Sender: TObject);
var
  CR: TTMSFNCDataGridCellCoord;
begin
  CR.Column := 7;
  CR.Row    := (Sender as TButton).Tag;
  GridPacjLegitym.FocusedCell := CR;
  GridDatabaseAdapter.SetActiveRecord(CR.Row);
  Dataset.Delete;
end;

So the issue is that when deleting a row at dataset level, potentially other rows could be affected. We implemented a way to make sure the data is properly loaded, but this means that the cell data is lost during the update. This actually also applies to sorting or filtering. When doing that operation the cell data (properties) are lost. This means the button you have connected to the grid is also lost. When binding to a database adapter you'll need to switch to a different technique.

procedure TForm9.TMSFNCDataGrid1CellButtonClick(Sender: TObject; AColumn,
  ARow: Integer);
var
  CR: TTMSFNCDataGridCellCoord;
begin
  CR := MakeCell(AColumn, ARow);
  TMSFNCDataGrid1.FocusedCell := CR;
  TMSFNCDataGridDatabaseAdapter1.SetActiveRecord(CR.Row);
  ClientDataSet1.Delete;
end;

procedure TForm9.TMSFNCDataGrid1GetCellClass(Sender: TObject; AColumn,
  ARow: Integer; var ACellClass: TTMSFNCDataGridCellClass);
var
  CR: TTMSFNCDataGridCellCoord;
begin
  if (AColumn = 7) and (ARow >= TMSFNCDataGrid1.FixedRowCount) then
    ACellClass := TTMSFNCDataGridButtonCell;
end;

procedure TForm9.TMSFNCDataGrid1GetCellProperties(Sender: TObject;
  ACell: TTMSFNCDataGridCell);
begin
  if ACell.IsButtonCell then
    ACell.AsButtonCell.Button.Caption := 'Delete';
end;

Unfortulatelly is still the same. Maybe third-party components spoil something. I'm using Almediadev StyleControls VCL components: PageViewer and PageControl. I used your demo Biolife ClientDataSet, to implement my method, and it works fine.
Biolife_ClientDataSet.zip (347.2 KB)

With the adapted demo I can indeed not reproduce the issue. Please let me know if I can be of assistance, or you have a reproducible case.

Not sure if you are using the latest version?

I'm using the latest version. I'll investigate the problem at my side. I'll try to prepare a reproducible case. Apart from my problem, different technique you suggested is very clever, I'll switch to it. Thanks.

1 Like