Я использую TGridPanel
для хранения некоторых панелей. Во время разработки я установил панель сетки на 1 строку и 5 столбцов.Получение индекса столбца щелкнутого элемента управления в TGridPanel
я могу добавить панель к сетке с помощью этого кода, который хорошо работает:
procedure TForm6.AddPanelToGrid(const ACaption: string);
var
pnl: TPanel;
begin
pnl := TPanel.Create(gpOne);
pnl.Caption := ACaption;
pnl.Parent := gpOne;
pnl.Name := 'pnlName' + ACaption;
pnl.OnClick := gpOne.OnClick;
pnl.ParentBackground := false;
pnl.ParentColor := false;
pnl.Color := clLime;
pnl.Font.Size := 14;
gpOne.ControlCollection.AddControl(pnl);
pnl.Height := pnl.Width;
end;
То, что я хочу сделать, это удалить TPanel
из сетки, когда я нажимаю на него (именно поэтому у меня есть установите обработчик по щелчку на панели сетки в приведенном выше коде).
В этом обработчике щелчка я делаю это, что почти работает:
procedure TForm6.gpOneClick(Sender: TObject);
begin
if not (sender is TPanel) then exit;
gpOne.ControlCollection.RemoveControl(Sender as TPanel);
(Sender as TPanel).Free;
gpOne.UpdateControlsColumn(0); <<<-------
gpOne.UpdateControlsRow(0);
gpOne.Refresh();
end;
Использование параметра для UpdateControlColumn()
вызывает порядок панелей в сетке, чтобы изменить - первый и второй поменяться местами.
Я могу обойти это, добавив столбец idex в свойство тега панели, а затем передать это UpdateControlColumn(). Затем это работает, но как только панель была удалена, более высокие номера тегов больше не действительны - панели переместили столбец.
Итак, как я могу получить столбец, в котором находится панель из обработчика OnClick
?
Я использую Delphi 10.1 Berlin - если это имеет значение.
Чтобы проверить это, я начал новый проект, добавил TGridPanel
, установил его, чтобы иметь 1 строку и 5 одинаково разветвленных столбцов. Я добавил 6 TButton
управления и создал OnClick
обработчик для каждого с помощью следующего кода:
AddPanelToGrid('One'); // changing the string for each button.
Нажмите несколько кнопок, чтобы добавить несколько панелей, а затем нажмите на панели, чтобы удалить их.
Это никогда не может быть безопасным для вызова 'Free()' в 'Sender' события, пока вы все еще находитесь внутри обработчика событий. RTL по-прежнему нуждается в доступе к объекту после выхода обработчика события. Если вам нужно освободить «Отправитель», вы должны * задержать освобождение до окончания выхода обработчика.Обычно я делаю это с помощью 'PostMessage()', чтобы опубликовать собственное пользовательское окно с указателем объекта в 'LParam', а затем позволить обработчику сообщения освободить объект, когда это безопасно. Это похоже на то, как 'TForm' использует' CM_RELEASE' для освобождения себя, когда обработчик события OnClose возвращает «Action = caFree' –
Спасибо, @RemyLebeau, если я продолжу этот метод, я включу ваше предложение. С наилучшими пожеланиями, –