Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Обращение к динамически созданным объектам Delphi


Автор: Arinna 15.8.2011, 19:55
Здравствуйте!
Я динамически на Form1 создаю вкладки TabSheet  и на каждой из них таблицы StringGrid. Нужно заполнять эти таблицы данными из Form2, или из Form3 и т.д (пользователь сам выбирает). Как мне в каждой форме обращаться к динамически созданному StringGrid?


Автор: Frees 15.8.2011, 20:04
а ты сслки на созданные объекты сохраняй... в TList например, или можно FindWindow использовать

Автор: Arinna 15.8.2011, 20:10
А можно так?

S:=TStringGrid(Form1.FindComponent('StringGrid1'));
S.Cells[0,1]:='1'; 

но тут ошибка... Вы не подскажете как правильно будет? А то я с ссылками что то не поняла...

Автор: Frees 15.8.2011, 20:15
А при создании компонентов вы какое имя им давали?, его и пишите в FindControl

Автор: Arinna 15.8.2011, 20:24
Там на этой форме есть StringGrid1.

Код

For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2.PageControl1.Pages[i]);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(i);
  Options:=Options+[goEditing];
  Left:=3;
  Top:=50;
  FixedCols:=0;
  end;
end;


Вот... Я просто первый раз работаю с динамическими объектами... И вообще ничего не знаю... Я не правильно обращаюсь? Как надо написать? Куда писать FindControl? Я не поняла)

Автор: northener 15.8.2011, 20:36
Цитата(Arinna @  15.8.2011,  20:24 Найти цитируемый пост)
S:=TStringGrid.Create(Form2.PageControl1.Pages[i]);

Замените на
Код

  S:=TStringGrid.Create(Form2);


Автор: Arinna 15.8.2011, 20:39
Если я так сделаю, то таблица будет на форме, а не на вкладках. Я уже так делала) Получалась одна таблица.

Автор: maniaks1 15.8.2011, 20:43
Лучше всего в данной ситуации создать наследника от TabSheet
с StringGrid.

Т.е. у каждой вкладки будет свой StringGrid

Таким образом всё становится очень просто:
Допустим наш клас TMyTabSheet

перебираем все, находим нужный по заголовку или по тегу (присваиваем заранее)

Код


for i:=0 to ComponentCount-1 do
if Components[i] is TMyTabSheet then (Components[i] as TMyTabSheet).StringGrid.....




Не забываем о создании StringGrid про создании вкладки и удалении, при удалении вкладки.
Если надо могу подкинуть пример.

Автор: Arinna 15.8.2011, 20:45
northener, хотя вроде я сейчас так сделала и получилось... если что, я вернусь))) Спасибо)

Добавлено через 1 минуту и 18 секунд
maniaks1, если не сложно, то давайте...

Автор: northener 15.8.2011, 20:49
Цитата(Arinna @  15.8.2011,  20:39 Найти цитируемый пост)
Если я так сделаю, то таблица будет на форме, а не на вкладках.

Тот контрол, на котором будет лежать таблица определяется не владельцем, а родителем и задается в этой строке:

Цитата(Arinna @  15.8.2011,  20:24 Найти цитируемый пост)
Parent:=Form2.PageControl1.Pages[i];


Автор: Arinna 15.8.2011, 20:58
Нет... Для 

Код

TStringGrid(Form2.FindComponent('StringGrid0')).Cells[0,1]:='1' 

заработал, а вот

Код

TStringGrid(Form2.FindComponent('StringGrid1')).Cells[0,1]:='1'
  
нет почему то...( вообще я создаю по две таблицы на TabSheet. И Когда я исправила на
Код

S:=TStringGrid.Create(Form2);
 

Выдает ошибку A component named StringGrid2 already exists
Вот кусок кода с созданием двух Гридов на вкладке
Код

For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(i);
  Options:=Options+[goEditing];
  Left:=3;
  Top:=50;
  FixedCols:=0;
  end;
end;

For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(Pagecontrol1.PageCount+i);
  Options:=Options+[goEditing];
  Left:=525;
  Top:=50;
    FixedCols:=0;
  end;
end;
 

Автор: maniaks1 15.8.2011, 21:01
Код

type
  TMyTabSheet=class(TTabSheet)
  ScrollBox:TScrollBox;
  //Тут можно написать необходимые процедуры
  procedure aaa;
protected
public
  isSave:Boolean;
end;

procedure TMyTabSheet.aaa;
begin
  //
end;



Далее где нужно:

Код

var T: TMyTabSheet;
begin
  T := TMyTabSheet.Create(PageControl1);
  with T do
  begin
    Visible := True;
     Caption := 'Эксперимент  '+InttoStr(Random(100));
    PageControl:= PageControl1;  // Назначаем Tab в Page Control
    PageControl1.ActivePage:=T;  //Устанавливаем новую закладку активной

    //Создаём ScrollBox
    ScrollBox:=TScrollBox.Create(T);
    ScrollBox.Align:=alClient;
    ScrollBox.Parent:=T;

    T.isSave:=true;

  end;
  T:=Nil;
  T.Free;
end;



Удаление:

Код

if PageControl1.PageCount=0 then Exit;

//если надо, сохраняем...
if (PageControl1.ActivePage as TMyTabSheet).isSave ...

 FreeAndNil((PageControl1.ActivePage as TMyTabSheet).ScrollBox);
(PageControl1.ActivePage as TMyTabSheet).Free;



Возможны небольшие ошибки, но смысл думаю понятен.
Насчёт поиска вкладок наврал, надо приблизительно так:

Код

for i:=0 to PageControl1.PageCount-1 do
if (PageControl1.Pages[i] as TMyTabSheet).Caption='dgsdgsd' then
(PageControl1.Pages[i] as TMyTabSheet).ScrollBox .....

Автор: northener 15.8.2011, 21:07
Цитата(Arinna @  15.8.2011,  20:58 Найти цитируемый пост)
For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(i); При PageCount = 2 тут создаются StringGrid0 и StringGrid1
  Options:=Options+[goEditing];
  Left:=3;
  Top:=50;
  FixedCols:=0;
  end;
end;
For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(Pagecontrol1.PageCount+i);  А тут создаются StringGrid1 и StringGrid2
  Options:=Options+[goEditing];
  Left:=525;
  Top:=50;
    FixedCols:=0;
  end;
end;


Автор: Arinna 15.8.2011, 21:14
Почему?
Код

name := 'StringGrid'+inttostr(Pagecontrol1.PageCount+i);   создаются StringGrid1 и StringGrid2


Ведь Pagecontrol1.PageCount=2.
Тогда Pagecontrol1.PageCount+0=2 и Pagecontrol1.PageCount+1=3...
Или я что то не так понимаю?...

Автор: northener 15.8.2011, 21:19
Цитата(Arinna @  15.8.2011,  21:14 Найти цитируемый пост)
Тогда Pagecontrol1.PageCount+0=2 и Pagecontrol1.PageCount+1=3

Извините. Это я ошибся.
Значит ошибка где-то в другом месте.

Автор: Arinna 15.8.2011, 21:27
Вы меня на мысль навели... Спасибо!!! я исправила чуть и заработало))))
Вот исправленный код. Вдруг кому поможет...
Код

For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(i); 
  Options:=Options+[goEditing];
  Left:=3;
  Top:=50;
  FixedCols:=0;
  end;
end;
For i:=0 to Form2.Pagecontrol1.PageCount-1 do begin
  S:=TStringGrid.Create(Form2);
   with S do
  begin
  Parent:=Form2.PageControl1.Pages[i];
  Visible := True;
  name := 'StringGrid'+inttostr(Pagecontrol1.PageCount*2+1+i); 
  Options:=Options+[goEditing];
  Left:=525;
  Top:=50;
    FixedCols:=0;
  end;
end;


И обращаюсь вот так
Код

TStringGrid(Form2.FindComponent('StringGrid1')).Cells[0,1]:='1'

Автор: northener 15.8.2011, 23:37
Цитата(Arinna @  15.8.2011,  21:27 Найти цитируемый пост)
Вы меня на мысль навели... Спасибо!!! я исправила чуть и заработало))))

Счастлив что хоть чем-то помог.
Не могу только понять зачем нужно 
Код

Pagecontrol1.PageCount*2+1
?
Ну да это и не мое дело. smile

Автор: CodeMonkey 16.8.2011, 01:45
Немного поздно, но рекомендую почитать на досуге: http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=342

Автор: Arinna 16.8.2011, 09:06
northener, Вы правы. Вместо 

Код
    
Pagecontrol1.PageCount*2+1


Нужно оставить просто

Код

Form2.Pagecontrol1.PageCount


Автор: Arinna 16.8.2011, 10:42
CodeMonkey, спасибо за ссылку.) Мне это еще пригодится)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)