Проблема с вашим кодом в том, что вы удаляете кнопку, действие которой выполняется в данный момент. Когда действие возвращается, кнопка больше не существует, на Windows она освобождается на DisposeOf()
, а на мобильных платформах она находится в состоянии "zomb ie".
Лечение заключается в отложить удаление кнопок до завершения действия. В стандартном приложении Windows я отправляю сообщение самому себе, чтобы убедиться, что действие завершено, прежде чем я получу сообщение и смогу вызвать CreateNavPanelButtons()
. Но я не уверен, что это будет работать на всех других платформах.
Следующее должно работать на любой платформе.
Добавить TTimer
, Enabled = False
, Interval = 1
. Затем объявите приватное поле формы, Action: TAction
.
Измените любые обработчики действий, которые изменяют NavPanelButtons
следующим образом:
procedure TForm2.acNextMenuExecute(Sender: TObject);
begin
// CreateNavPanelButtons(acBackToMainMenu);
Action := acBackToMainMenu;
Timer1.Enabled := True;
end;
И добавьте событие OnTimer
procedure TForm2.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
if Action <> nil then
CreateNavPanelButtons(Action);
end;
Обновление, позволяющее избежать TTimer
Еще одним решением, не требующим сообщений или таймеров, было бы создание всех кнопок спереди и их удаление. вообще во время выполнения программы.
Они могут быть сгруппированы в TButtonList
списки, которые будут содержать кнопки, которые связаны и отображаются одновременно.
Когда необходимо отобразить TButtonList
, старые кнопки в NavPanel
нужно будет удалить (не B.DisposeOf
) с панели только с помощью NavPanel.RemoveObject(B)
в oop.
Наконец, новый список кнопок будет добавлен на панель: for b in ButtonList do NavPanel.AddObject(b)
.
Недостатком этого является большее использование памяти, если это имеет значение.