Search code examples
delphitlist

TCategoryPanelGroup, delete panel


Working on Delphi XE2, no 3rd party components/suites, nothing fancy.

Got a TCategoryPanelGroup (catPanGroup) on a form. I can easily add as many TCategoryPanel(s) as I need with:

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;

I don't care about the panel order, don't care (yet) how it looks, I can insert labels, textboxes and buttons inside these panels, they work as they should, no problems. I exit the application and no (apparent) leaks.

However, the application its a bit dynamic and need to remove a panel, lets say the last one. So, my immediate reaction is to:

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

Or:

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

Even:

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;

And when things were not working I:

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

So ¿what's the error? On some cases there is no error but when I exit the application I always get an exception (access violation). ¿Maybe comes from the controls that I inserted inside the TCategoryPanel? Nope, I still get access violations without creating any controls on those panels. And the exception only pops when I delete (or try to delete) a panel. Will try at home on XE3 shortly.

¿Is anybody able to create and delete a TCategoryPanel on run-time?


Solution

  • The RemovePanel method is private, but you can use a class helper to gain access to such procedure.

    Try this

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

    And use like so

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