【问题标题】:TCategoryPanelGroup, delete panelTCategoryPanelGroup,删除面板
【发布时间】:2014-01-15 13:18:09
【问题描述】:

在 Delphi XE2 上工作,没有第 3 方组件/套件,没什么花哨的。

在表单上有一个 TCategoryPanelGroup (catPanGroup)。我可以根据需要轻松添加任意数量的 TCategoryPanel:

procedure TSomeForm.PopulateGrp(Sender: TObject);
var catPanel: TCategoryPanel;
  x: word;
begin
  x := 0;
  while x < 9 do
  begin
    catPanel := catPanGroup.CreatePanel(Self) as TCategoryPanel;
    // Also tried the line below, using the panel group as the owner
    // catPanel := catPanGroup.CreatePanel(catPanGroup) as TCategoryPanel;
    //it also works without the following line
    catPanel.PanelGroup := catPanGroup;
    catPanel.Caption := 'and nothing else matters';
    Inc(x);
  end; //loop
end;

我不关心面板的顺序,也不关心它的外观,我可以在这些面板中插入标签、文本框和按钮,它们可以正常工作,没有问题。我退出应用程序并且没有(明显的)泄漏。

但是,应用程序有点动态,需要删除一个面板,比如说最后一个。所以,我的第一反应是:

var catPanel: TCategoryPanel;
begin
  catPanel := catPanGroup.Panels[catPanGroup.Panels.Count - 1];
  catPanGroup.Panels.Remove(catPanel);
end;

或者:

var catPanel: TCategoryPanel;
begin
  catPanGroup.Panels.Delete(catPanGroup.Panels.Count - 1);
end;

偶数:

var catPanel: TCategoryPanel;
begin
  catPanel := catPanGroup.Panels[catPanGroup.Panels.Count - 1];
  catPanGroup.Panels.Remove(catPanel);
  catPanGroup.RemoveControl(catPanel);
  //catPanel.PanelGroup := nil; <- can't do, it raises an exception
end;

当事情不正常时,我:

  catPanGroup.Panels.Clear();
  //and rebuild every single panel

那么¿有什么错误?在某些情况下没有错误,但是当我退出应用程序时,我总是会遇到异常(访问冲突)。 ¿ 可能来自我在 TCategoryPanel 中插入的控件?不,如果没有在这些面板上创建任何控件,我仍然会遇到访问冲突。并且仅当我删除(或尝试删除)面板时才会弹出异常。不久将在 XE3 上试用。

¿有人可以在运行时创建和删除 TCategoryPanel 吗?

【问题讨论】:

    标签: delphi tlist


    【解决方案1】:

    RemovePanel 方法是私有的,但您可以使用类助手来访问此类过程。

    试试这个

    Type
      TCategoryPanelGroupHelper = class helper for TCustomCategoryPanelGroup
      public
        procedure RemovePanel_(Panel: TCustomCategoryPanel);
      end;
    
    { TCategoryPanelGroupHelper }
    
    procedure TCategoryPanelGroupHelper.RemovePanel_(Panel: TCustomCategoryPanel);
    begin
      Self.RemovePanel(Panel);
    end;
    

    像这样使用

      //This code will remove the first panel, be sure to check the bounds of the index passed.   
      catPanGroup.RemovePanel_(TCustomCategoryPanel(catPanGroup.Panels[0]));
    

    【讨论】:

    • 完美运行。谢谢。
    【解决方案2】:

    看起来好像面板永远不会被移除。 VCL 中的面板删除代码 (TCustomCategoryPanelGroup.RemovePanel) 是私有的,仅在类别面板析构函数中以及为面板设置新的父面板组时调用。在后一种情况下,VCL 确保新父级存在(不是 nil),否则引发异常。

    以下是一个不太好的解决方法,它创建一个临时面板组来托管要删除的面板:

    var
      catPanel: TCategoryPanel;
      dummy: TCategoryPanelGroup;
    begin
      catPanel := catPanGroup.Panels[catPanGroup.Panels.Count - 1];
    
      dummy := TCategoryPanelGroup.Create(nil);
      try
        dummy.Visible := False;
        dummy.Parent := Self;
        catPanel.PanelGroup := dummy;
      finally
        dummy.Free;
      end;
    

    【讨论】:

      【解决方案3】:

      这对我有用:

      procedure zapPanels(sender : tobject);
      var
      idx : integer;
      x : tCategoryPanel;
      begin
      for idx := ((sender as tCategoryPanelGroup).Panels.Count)-1 downto 0 do
        begin
        x := (sender as tCategoryPanelGroup).Panels.Items[idx];
        x.Destroy;
        end;
      end;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-20
        • 2011-09-20
        • 1970-01-01
        • 1970-01-01
        • 2018-01-11
        • 2012-02-12
        相关资源
        最近更新 更多