从TGridPanel中删除控件

时间:2016-06-02 10:47:43

标签: delphi gridpanel

我正在使用TGridPanel来管理许多面板。我创建面板并使用如下代码将它们添加到GridPanel:

var
  pnl: TPanel;
begin
  pnl := TPanel.Create(GridPanel2);
  pnl.Caption := 'Panel One';
  pnl.Tag := 1;
  pnl.Parent := GridPanel2;
  pnl.Name := 'pnlOne';

  GridPanel2.ControlCollection.AddControl(pnl);


  pnl := TPanel.Create(GridPanel2);
  pnl.Caption := 'Panel Two';
  pnl.Tag := 2;
  pnl.Parent := GridPanel2;
  pnl.Name := 'pnlTwo';

  GridPanel2.ControlCollection.AddControl(pnl);


  pnl := TPanel.Create(GridPanel2);
  pnl.Caption := 'Panel Three';
  pnl.Tag := 3;
  pnl.Parent := GridPanel2;
  pnl.Name := 'pnlThree';

  GridPanel2.ControlCollection.AddControl(pnl);
end;

您会注意到每个面板都有不同的标记值。

我想根据面板标签属性中的值从GridPanel中删除面板。我尝试了以下代码:

var
  ii: integer ;
  pnl: TPanel;
begin
  for ii := 0 to GridPanel2.ControlCollection.Count -1 do begin
    if GridPanel2.ControlCollection[ii].Control.Tag = 1 then begin
      pnl := GridPanel2.ControlCollection[ii].Control as TPanel;

      GridPanel2.ControlCollection.RemoveControl(pnl);

      freeandnil(pnl);
    end;
  end;
  gridpanel2.Refresh();
end;

这很有效,前提是面板是集合中的最后一个面板。如果我尝试删除tag = 1或tag = 2的面板,则会出现超出范围的错误。在调试器中单击“继续”将留下已删除面板所在的空间,因此请删除面板。

我希望看到的是,将面板2移除,随后的面板在一个地方拖曳,不留间隙。

我该怎么做?

如果重要的话,我正在使用Delphi 10.1柏林。

1 个答案:

答案 0 :(得分:2)

与从列表或集合中删除项目一样,您需要在计数更改时采取预防措施。 for循环计数在循环开始时确定。现在,如果您从列表中删除某个项目,那么当for循环持续到结束时,您将点击一个不存在的索引。

你可以通过多种方式避免这种情况,例如:一旦找到并删除了该项目,就可以通过突破循环。

  freeandnil(pnl);
  break;

另一种方法是向后运行for循环

  for ii := GridPanel2.ControlCollection.Count -1 downto 0 do begin

或者您可以使用Repeat UntilWhile循环来检查条件是否在循环的每个回合中继续。

要在删除项目后更新网格面板,请调用其中一个或两个

  gridpanel2.UpdateControlsRow();
  gridPanel2.UpdateControlsColumn();

然而,让订单正确起来感觉非常棘手