I'm using a TGridPanel
to hold some panels. At design time, I've set the grid panel to have 1 row and 5 columns.
I can add a panel to the grid using this code, which works well:
procedure TForm6.AddPanelToGrid(const ACaption: string);
var
pnl: TPanel;
begin
pnl := TPanel.Create(gpOne);
pnl.Caption := ACaption;
pnl.Parent := gpOne;
pnl.Name := 'pnlName' + ACaption;
pnl.OnClick := gpOne.OnClick;
pnl.ParentBackground := false;
pnl.ParentColor := false;
pnl.Color := clLime;
pnl.Font.Size := 14;
gpOne.ControlCollection.AddControl(pnl);
pnl.Height := pnl.Width;
end;
What I want to do is remove a TPanel
from the grid when I click on it (which is why I have set the on click handler to that of the grid panel in the above code).
In that click handler I do this, which almost works:
procedure TForm6.gpOneClick(Sender: TObject);
begin
if not (sender is TPanel) then exit;
gpOne.ControlCollection.RemoveControl(Sender as TPanel);
(Sender as TPanel).Free;
gpOne.UpdateControlsColumn( 0 ); <<<-------
gpOne.UpdateControlsRow(0);
gpOne.Refresh();
end;
Using a parameter for UpdateControlColumn()
causes the order of the panels in the grid to change - the first and second swap places.
I can get around this by adding the column idex to the panel's tag property, then pass that to UpdateControlColumn(). This then works, but once a panel has been removed the higher tag numbers are no longer valid - the panels have moved column.
So, how can I get the column that a panel is in from within the OnClick
handler?
I'm using Delphi 10.1 Berlin - if that makes any difference.
To test this, I started a new project, added a TGridPanel
, set it to have 1 row and 5 equally widthed columns. I added 6 TButton
controls and created an OnClick
handler for each with the following code:
AddPanelToGrid('One'); // changing the string for each button.
Click a few buttons to add some panels, then click the panels to remove them.
TCustomGridPanel has a pair of useful functions,
CellIndexToCell()
andCellToCellIndex
, but they are not public and thus not directly accessible from a TGridPanel.To make them available declare
TGridPanel
anew as below:Then add
r
andc
variables for row and col, add the call toCellIndexToCell()
and usec
as argument forUpdateControlsColumn
:And follow advise of Remy Lebeau, regarding freeing the panel. ( I just noticed his comment).
If you haven't already, you may also want to take a look at
TFlowPanel
and itsFlowStyle
property.TflowPanel
reordering after deletion is more predictable if you use more than one row, but depends of course on what you need.