Форум: "Начинающим";
Текущий архив: 2015.12.06;
Скачать: [xml.tar.bz2];
ВнизКак удалить динамически созданный контрол Найти похожие ветки
← →
Sakipiel (2014-06-05 15:52) [0]Есть панель, на нее программно создаются контролы.
Задача:
при нажатии на кнопку Delete удалить активный контрол с панели и вообще удалить.
Проблема:
Событие OnkeyDown активизируется в том самом контроле. В панели на которую он ложится OnkeyDown нет вообще. ну и когда мы из самого контрола, а именно события OnKeyDown вызываем
if Key = VK_DELETE then
If Assigned(ActiveControl) Then
ActiveControl.RemoveControl(ActiveControl);
то получаем ошибку, вообщем отказывается он удалять самого себя, а что делать?
← →
Sakipiel (2014-06-05 16:09) [1]
if Key = VK_DELETE then
If Assigned(ActiveControl) Then
(Sender as TControl).Owner.RemoveComponent(ActiveControl);
и так ниале
← →
mfender © (2014-06-05 16:09) [2]
if Assigned(TControl(Sender)) then
TControl(Sender).Parent.RemoveControl(TControl(Sender));
← →
Sakipiel (2014-06-05 16:17) [3]спс )
← →
Sakipiel (2014-06-07 03:11) [4]Вопрос на засыпку, а что делать с контролами у которых OnKeyDown нет? Tlabel например...
← →
Leonid Troyanovsky © (2014-06-07 08:25) [5]
> Sakipiel (05.06.14 15:52)
Во-первых, RemoveControl - это не "вообще удалить",
а удалить из списка контролов. See also: InsertControl.
Во-вторых, OnKeyDown у панели есть, просто оно protected.
В-третьих, удалять контрол из его же обработчика - не очень
хорошая идея.
Я бы сделал HitList: TObjectList и очищал его (Clear),
скажем, в Application.OnIdle (See TApplicationEvents).
Т.е., если контрол стал не нужен, то добавим его в список.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2014-06-07 08:29) [6]
> Sakipiel (07.06.14 03:11) [4]
Ну, можно, например, у панели сделать контекстное меню,
с помощью которого можно удалить (добавить, переместить, ..) контрол. See also: HotKey, TAction &etc.
--
Regards, LVT.
← →
Юрий Зотов © (2014-06-07 13:47) [7]Безопасный вариант.
Из обработчика контрола посылаем форме (через PostMessage) юзерское сообщение, передавая контрол через параметры. Получив это сообщение, форма удаляет контрол.
← →
Sakipiel (2014-06-19 17:27) [8]да, но из какого обработчика? в Tlabel нет OnKeyDown, не модифицировать же мне теперь все контролы
← →
Германн © (2014-06-19 17:35) [9]
> в Tlabel нет OnKeyDown
Значит для TLabel и не существует проблемы описанной в топике.
← →
Dimka Maslov © (2014-06-19 17:40) [10]Ставим форме KeyPreview (или как там оно называется) в true и спокойно обрабатываем удаление контролов в OnKeyDown формы.
Что же касается TLabel, то в силу определённых причин оно не может быть активным контролом. Никогда.
← →
Sakipiel (2014-06-19 19:54) [11]непонятная ботва,
LastSelectedControl.Parent.RemoveControl(LastSelectedControl);
LastSelectedControl.free;
делаю я, где LastSelectedControl это переменная в которой хранится указатель на компонент, все проходит, но есть еще 1 переменная в которой также хранится указатель на этот компонент, и вот после того что я сделал, что должно остаться в той переменной? Ибо она проходит проверку
if not Assigned(C) then
exit;
т.е. получается что оно вполне себе Assigned после удаления. Причем можно посмотреть его ClassName, как так то? что делать?
← →
Inovet © (2014-06-19 20:27) [12]> [11] Sakipiel (19.06.14 19:54)
> как так то?
Во-первых, кто ж за тебя её будет обниливать. Во-вторых, надо проверить - всё ли в порядке с логикой, если после удаления надо проверять на удалённость.
← →
Sakipiel (2014-06-19 20:51) [13]мде, чо ж оно не обниливаецо само, а то удаляешь удаляешь, удаляешь, удаляешь, а ничего не удаляется. с логикой все в порядке, просто я не люблю делать компоненты которые в каждой непонятной ситуации (как то неназначеная ссылка на компонент) будет вываливать Аксесс виалейшн, и чтобы я потом долго размышлял, и что же это за беда то такая. У меня есть мой компонент, который вокруг этого рисует рамку и в нем на него ссылка, и ее он и проверяет, перед тем как перерисовать рамку, и получается, если я удаляю компонент, то мне придется вручную обниливать все ссылки..нет их конечно не много, но все равно обидно чо та.
← →
Sakipiel (2014-06-19 20:58) [14]
procedure TDesForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
//var
// s:string;
begin
if Key = VK_DELETE then
if Assigned(LastSelectedControl) then
begin
//s := TControl(Sender).Name;
MarkControlAsDeleted(LastSelectedControl.Name);
DeleteSelectedComponentFromPointerList;
LastSelectedControl.Parent.RemoveControl(LastSelectedControl);
LastSelectedControl.free;
LastSelectedControl := nil;
SetFocus(LastSelectedControl);
end;
end;
мде вот она и случилась непонятная ситуация. весь код проходит, останавливаемся отладчиком на последнем end, жмем F7 и получаем ошибку чтения памяти...я чета без идей )
← →
brother © (2014-06-19 21:00) [15]1.
> LastSelectedControl.free;
> LastSelectedControl := nil;
freeandnil
2.
> SetFocus(LastSelectedControl);
он уже мертв!
← →
brother © (2014-06-19 21:04) [16]ps. используйте отладчик и точки останова чтобы выловить причину и точное место AV
← →
Sakipiel (2014-06-19 21:04) [17]LastSelectedControl.free; а если не делать этого, то эта ошибка не появляется
> он уже мертв!
это моя процедура и она рисует рамку вокруг компонента, а если он уже мертв, то она ее стирает.
← →
Sakipiel (2014-06-19 21:06) [18]
> ps. используйте отладчик и точки останова чтобы выловить
> причину и точное место AV
так я именно это и делал, я же говорю весь код проходит без ошибок, вылет происходит на выходе из FormKeyDown, причем я жму F7 т.е. отладчик туда где ошибка меня не пускает.
← →
Sakipiel (2014-06-19 21:18) [19]может он после FormKeyDown пытается вызвать OnkeyDown компонента? а компонента уже нет? и вот результат...
← →
Sakipiel (2014-06-19 21:20) [20]в подтверждение моей теории TLabel удаление таким образом не вызывает ошибки, т.к. у него нет OnkeyDown события. Так что метод че то дал сбой) как удалить контрол? ))
← →
Плохиш © (2014-06-19 21:38) [21]Ещë один горе-кодер, за которым пушкин подчищать ссылки.
Запомни: это программирование, здесь тебе никто и ничего не должен, всë что накодил, должен сам и подчистить за собой.
← →
Германн © (2014-06-19 22:00) [22]
> с логикой все в порядке
Как раз наоборот. Класс не может знать в каких переменных содержатся ссылки на него и сколько их вообще этих переменных.
← →
Sakipiel (2014-06-19 22:59) [23]уже начал изучать TApplicationEvents, как вдруг пришло гениальное решение. Сделать это не в кейдауне, а в кейапе, тогда косяка нет.
← →
Юрий Зотов © (2014-06-19 23:11) [24]> Sakipiel (19.06.14 22:59) [23]
> Сделать это не в кейдауне, а в кейапе, тогда косяка нет.
Необнуленная ссылка на уже уничтоженный компонент - это скрытый косяк. И корень зла. Если Вы это корень не уберете, то рано или поздно он себя все равно проявит. И никакие кейдауны тогда уже не помогут. Исправлять надо саму причину, а не ее следствие.
← →
Sakipiel (2014-06-19 23:54) [25]омг, я уже давно все обнулил, я же сказал ошибка не в моем коде вылазила, свои соображения по поводу того что происходило я выше написал, что я сделаю то с этим?
← →
Inovet © (2014-06-20 00:41) [26]> [25] Sakipiel (19.06.14 23:54)
> я же сказал ошибка не в моем коде вылазила
А, Снова Билл Гейтс? Или про него уже не помнят?
← →
Inovet © (2014-06-20 00:43) [27]> [25] Sakipiel (19.06.14 23:54)
> я уже давно все обнулил
Перечитать
> [12] Inovet © (19.06.14 20:27)
> Во-вторых, надо проверить - всё ли в порядке с логикой,
> если после удаления надо проверять на удалённость.
← →
Sakipiel (2014-06-20 04:08) [28]ну может вы сначала попробуете удалить компонент так, а потом расскажете как у вас это получилось ) мою процедуру можно вообще закомментировать, она ничего не меняет.
← →
Inovet © (2014-06-20 04:27) [29]> [28] Sakipiel (20.06.14 04:08)
Да пожалуйста
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(ActiveControl) then
begin
RemoveControl(ActiveControl);
end;
end;
И не надо, чтобы он самоудалялся. Удалять должен тот, кто создал, или владелец.
← →
Sakipiel (2014-06-20 05:04) [30]хе хе, тута нету Free, это раз, т.к. в этом вся фишка, контрол должен удалятся по кейдауну, а не по нажатии кнопки, из кейдауна формы. При этом фокус должен быть на удаляемом контроле в этот момент, чтобы он тоже получил кейдаун, вернее получать его будет уже не кому и вылезет ошибка о которой я говорил.
А делать Free научили меня вы. А создал я его програмно. Я ж начинающий я не знаю удалит его владелец и когда или нет
← →
Sakipiel (2014-06-20 05:06) [31]а то понимаешь, ссылки удаляй, чо как не программист, а контролы не удаляй, чо как не программист )
← →
brother © (2014-06-20 05:35) [32][29] Вы еще не устали с ним спорить? Ну уперся на кейдауне, пусть грабли ловит...
зы. автор, еще раз [24] + удаление объекта "из себя" ЗАПРЕЩАЮ! и [25] вызывает улыбку...
← →
brother © (2014-06-20 05:39) [33]меня так и тянет спросить: какое условие должно произойти, чтобы TLabel (если их несколько,то какой именно) нужно было удалять? ибо он не может быть в фокусе!
← →
Sakipiel (2014-06-20 06:19) [34]согласитесь это очень удобно, нажать делит, и чтобы все было. более того даже в делфи так оно и работает. Вот от этого я и пляшу. А раз так, то что же еще обрабатывать, как не онКейДаун? Хотя кейАп тоже нормально.
К каждому контролу при создании у меня прикрепляется онКлик, который записывает в отдельное поле владельца компонента ссылку на него, на котором кликнули, поэтому я всегда удаляю тот лабел, я не удаляю на данный момент активный контрол. Так что все пучком, довольно пессимизма.
← →
Sakipiel (2014-06-20 06:33) [35]
> Во-первых, RemoveControl - это не "вообще удалить",а удалить
> из списка контролов. See also: InsertControl.
вы мне писали.....после чего я начал делать Free, до этого я этого не делал, если владелец удалит, так я не против) не надо так не надо, я что против что ли )
← →
Inovet © (2014-06-20 06:48) [36]> [35] Sakipiel (20.06.14 06:33)
Подожди насчёт Free. Сначала расскажи, что хочешь получить, а не сразу о том, как это делаешь. Делаешь ты что-то не то, а что надо пока не ясно. Кто там кого и зачем должен удалять? Насовсем или как?
← →
Sakipiel (2014-06-20 07:27) [37]хочу получить дизайнер форм, для этого берем форму, кладем на нее панель - форма владелец всего, панель эмулирует ту форму которую мы разрабатываем и является родителем всех контролов. пользователь из списка выбирает контрол который он хочет добавить, он программно создается и появляется на панели. Если пользователь решил, что контрол не нужен, он его выделяет и жмет делит и контрол удаляется, вот что нужно ) в принципе все уже работает...
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2015.12.06;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.002 c