我正在使用TGridPanel来容纳一些面板。在设计时,我将网格面板设置为1行5列。

我可以使用以下代码将面板添加到网格,效果很好:

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;


我想做的是单击时从网格中删除TPanel(这就是为什么我在上面的代码中将onclick处理程序设置为网格面板的处理程序的原因)。

在该点击处理程序中,我这样做,几乎可以正常工作:

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;


UpdateControlColumn()使用参数会导致网格中面板的顺序更改-第一和第二交换位置。

我可以通过将列idex添加到面板的tag属性中,然后将其传递给UpdateControlColumn()来解决此问题。这样就可以了,但是一旦移除面板,更高的标签号将不再有效-面板已移动列。

那么,如何从OnClick处理程序中获取面板所在的列?

我正在使用Delphi 10.1 Berlin-如果有什么区别。

为了测试这一点,我开始了一个新项目,添加了TGridPanel,将其设置为具有1行和5个等宽列。我添加了6个TButton控件,并使用以下代码为每个控件创建了OnClick处理程序:

AddPanelToGrid('One');  // changing the string for each button.


单击一些按钮以添加一些面板,然后单击面板以将其删除。

最佳答案

TCustomGridPanel具有一对有用的函数CellIndexToCell()CellToCellIndex,但是它们不是公共的,因此不能从TGridPanel直接访问。

要使它们可用,请重新声明TGridPanel,如下所示:

type
  TGridPanel = class(Vcl.ExtCtrls.TGridPanel)  // add this
  end;                                         // -"-
  TForm27 = class(TForm)
    Button1: TButton;
    gpOne: TGridPanel;
    ...
  end;


然后为row和col添加rc变量,将调用添加到CellIndexToCell()并将c用作UpdateControlsColumn的参数:

procedure TForm27.gpOneClick(Sender: TObject);
var
  r, c: integer;
begin
  if not (sender is TPanel) then exit;

  gpOne.CellIndexToCell(gpOne.ControlCollection.IndexOf(Sender as TPanel), c, r); // add this

  gpOne.ControlCollection.RemoveControl(Sender as TPanel);
  (Sender as TPanel).Free;

  gpOne.UpdateControlsColumn( c );  // <<<-------
  gpOne.UpdateControlsRow(0);

  gpOne.Refresh();
end;


并按照Remy Lebeau的建议释放面板。 (我刚刚注意到他的评论)。



如果还没有,您可能还想看看TFlowPanel及其FlowStyle属性。如果使用多个行,则删除后的TflowPanel重新排序更可预测,但当然取决于您需要什么。

关于delphi - 在TGridPanel中获取单击的控件的列索引,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38977196/

10-10 16:55