| 
| 
 | Вопрос # 511/ вопрос решён / | 
 |  Здравствуйте, уважаемые эксперты!я динамически (runtime) создаю элементы управления. Как к ним обращаться потом?
 
|  |   Вопрос задал: Alexey-955 (статус: Посетитель)Вопрос отправлен: 22 апреля 2007, 12:36
 Состояние вопроса: решён, ответов: 4.
 |  Ответ #1. Отвечает эксперт: Dron Здравствуйте, Alexey!Чтобы обращаться к элементам, нужно при создании присвоить им имя (Name). Например, если динамически создаются 5 кнопок, то следует добавить такой код:
 Button.Name:='Button'+IntToStr(I);
 Здесь I - переменная-счётчик, которая проходит значения от 1 до 5. После этого кнопку можно "найти" по имени:
 TButton(FindComponent('Button5')).Caption:='Выход';
 Метод FindComponent есть у формы, именно его и следует вызывать. На вход ему подаётся имя, по которому он ищет элемент. Ну а затем обычное приведение типов - в данном случае к TButton.
 Желаю удачи!
 
|  | Ответ отправил: Dron (статус: Студент)Время отправки: 22 апреля 2007, 12:48
 Оценка за ответ: 5
 Комментарий к оценке: THNX про FindComponent я не знал |  Ответ #2. Отвечает эксперт: Вадим К Я в своё время использовал следующую технологию. Мне на форме нужно было от десяти до 30 кнопок(так хотел заказчик). Кнопки нужно было создавать динамически по данным с базы. Ниже приведён кусок кода, который я использовал (это только идея)type
 TBut = record
 Button:TButton;
 Data:string;
 Index:integer;
 end;
 TArrBut = array of TBut;
 
 var ab:TArrBut;
 //Загрузка с файла
 var i,len:integer;
 begin
 ...
 Setlength(ab,len);
 for i:=0 to len-1 do begin
 ab.button[I]:=TButton.Create(Form1);
 with ab.button[I] do
 begin
 Parent:=form1;
 Top:=i*20+10;
 Tag:=i;
 ....
 OnClick:=MyButtonClick;
 ....
 end;
 end;
 
 Обработчик нажатия MyButtonClick
 procedure TForm1.MyButtonClick(Sender:TObgect)
 var i:integer;
 b:TBut;
 begin
 i:=TButton(Sender).tag;
 if i>length(ab) then
 raise Except.Create('Глюк');
 b:=ab[I];
 //тут мы имеем все данные на кнопку, можем запросы к базе клепать.
 end;
 //Пусть мы решили на некоторых кнопках поменять Caption
 var i:integer;
 begin
 for i:=0 to length(ab) do
 begin
 if ab[I].index>10 then
 ab[I].button.Caption :='Yes';
 end;
 end;
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 22 апреля 2007, 13:18
 Оценка за ответ: 5
 |  Ответ #3. Отвечает эксперт: ANBsoft В принципе выше описали идеи, приведу кусок своего кода, в нем на форме формируется массив кнопок, данные для которого считываются из базы данных: ButtonArray - переменная в которой все это хранится. В обработчике нажатия кнопки TSpeedButton(Sender).Tag содержит ключевое поле требуемого товара для нахождения по Locate без долгих поисков и перебора всех кнопок.Надеюсь поможет, успехов.
 Приложение:Переключить в обычный режим Var ButtonArray:Array[1..99,1..99] of TSpeedButton; Procedure TFormProd.LoadTowar;Var n,f,k:Integer;    s:String;Begin  DeletTowar;  QSpisok.Open;  QSpisok.First;  while Not QSpisok.Eof do begin    n:=QSpisokK_Y.AsInteger;    f:=QSpisokK_X.AsInteger;    ButtonArray[n,f]:=TSpeedButton.Create(ScrollBox1);    ButtonArray[n,f].Parent:=ScrollBox1;    ButtonArray[n,f].Tag:=QSpisokID.AsInteger;    ButtonArray[n,f].Left:=f*KeyStep+(f-1)*KeyWidth;    ButtonArray[n,f].Top:=n*KeyStep+(n-1)*KeyHeight;    ButtonArray[n,f].Width:=KeyWidth;    ButtonArray[n,f].Height:=KeyHeight;    ButtonArray[n,f].Font.Size:=KeyFont;    ButtonArray[n,f].OnClick:=SpeedButtonClick;    s:=QSpisokName.AsString;    for k:=1 to Length(s) do      if s[k]='|' then s[k]:=#10;    ButtonArray[n,f].Caption:=s;    ButtonArray[n,f].Font.Color:=QSpisokColor.AsInteger;    if QSpisokFontSize.AsInteger=0 then      ButtonArray[n,f].Font.Size:=KeyFont    else      ButtonArray[n,f].Font.Size:=QSpisokFontSize.AsInteger;    if QSpisokFontBold.AsInteger=0 then      ButtonArray[n,f].Font.Style:=[]    else      ButtonArray[n,f].Font.Style:=[fsBold];    QSpisok.Next;  end;  QSpisok.CLose;End;  
|  | Ответ отправил: ANBsoft (статус: Студент)Время отправки: 23 апреля 2007, 08:41
 
 |  Ответ #4. Отвечает эксперт: min@y™ А я делал немного по-другому.Мне было необходимо динамически создавать/удалять/двигать/менять размеры мышью/запоминать и восстанавливать их количество и месторасположение неких самодельных потомков от TPanel. Причём их количество заранее неизвестно и неограничено.
 
 Так вот, при создании очередной такой панели, я заносил её в список-потомок TList, НЕприсваивая свойство Name (чтобы исключить конфликт идентичных имён). Естественно, у своего потомка TList (лучше бы воспользовался, конечно, TObjectList), я сделал дополнительное свойство
 
 property Panels[const Index: Integer]: TSizePanel read GetPanel;
 
 и функцию для реализации чтения свойства
 
 function GetPanel(const Index: Integer): TSizePanel;
 
 а также функции добавления, удаления и пр.
 
 Как к ним обращаться потом?
 А вот, например, так:
 
 PanelList.AddPanel(TSizePanel.Create(Self));
 PanelList.Panels[0].Parent:= MainScrollBox;
 PanelList.Panels[0].Color:= clRed;
 PanelList.Panels[0].Left:= 100;
 
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 23 апреля 2007, 08:47
 
 |  
 Мини-форум вопросаВсего сообщений: 0. 31 января 2011, 20:00: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5) Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |