Delphi firemonkey, как программно удалить пункт меню?

Как удалить пункт меню, который я динамически добавил в меню?

Я динамически добавляю пункты меню, например:

m:=TMenuItem.Create(nil);
m.Text:='bla bla bla';
mnuMain.AddObject(m);

Я не мог найти ЛЮБУЮ функцию, чтобы удалить запись снова. Я попытался удалить, освободить, удалить объект и т. Д., И элемент все еще не удален и все еще видим В чем подвох?

2 ответа

Если вы добавляете элемент вроде так:

var
    M : TMenuItem;
begin
    M := TMenuItem.Create(nil);
    M.Text := 'Bla Bla Bla';
    MenuBar1.AddObject(M);

Затем вы просто даете ему родителя, просто установите родителя пунктов меню в nil Затем ARC подключится и сделает все остальное, поскольку больше нет ссылок на объект.

Просто напишите цикл для прохождения и установите для всех родителей значение nil / Или, если вы также нацелены на Windows (или только на Windows) в своем коде, используйте DisposeOf или используйте директивы компилятора

var
  I: Integer;
begin
    for I :=  MenuBar1.ItemsCount-1 downto 0 do
    begin
       {$IFNDEF AUTOREFCOUNT}
         MenuBar1.Items[I].disposeOf;
       {$ELSE}
         MenuBar1.Items[I].parent := nil;
       {$ENDIF}
    end;
end;

Я столкнулся с той же проблемой: TMenuItem.RemoveObject не работает и закрытый член FContent TMenuView недоступен без хитростей через RTTI. Вот почему я создаю свой собственный обходной путь, используя список строк, в котором хранятся оставшиеся дочерние элементы меню, прежде чем я вызову TMenuItem.Clear:

function RemoveFromMenu(mnuMain: TMenuItem; const MenuText: string);
var
  list: TStringList;
  c: integer;
  Menu: TMenuItem;
begin
  list := TStringList.Create;
  try
    for c := 0 to mnuMain.ItemsCount - 1 do
    if mnuMain.Items[c].Text <> MenuText then
      list.Add(mnuMain.Items[c].Text);
    mnuMain.Clear;
    for c := 0 to list.Count - 1 do
    begin
      Menu := TMenuItem.Create(self);
      Menu.Text := list[c];
      Menu.OnClick := mnuMainSubMenuClick; // The menu event handler
      mnuMain.InsertObject(0, Menu);
    end;
  finally
    list.Free;
  end;
end;

В случае, если ваше подменю имеет для каждого пункта меню собственный обработчик меню, вы также можете сохранить этот обработчик событий. В таких ситуациях общий список TMenuItem (TList) будет лучшим подходом, чем использование списка строк.

Другие вопросы по тегам