|
Вопрос # 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)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|