TCategoryPanelGroup, удалить панель

Работает на Delphi XE2, никаких сторонних компонентов/комплектов, ничего необычного.

Получил 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;

Or:

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 во время выполнения?


person Gixabel    schedule 27.12.2013    source источник


Ответы (3)


Метод 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]));
person RRUZ    schedule 28.12.2013
comment
Работает отлично. Спасибо. - person Gixabel; 28.12.2013

Похоже, что панель никогда не должна сниматься. Код удаления панели в 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;
person Sertac Akyuz    schedule 28.12.2013

Это работает для меня:

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;
person Chris Moore    schedule 13.07.2018