-
Собственно вопрос такой: какой механизм создания дочерних объектов в design-time?
Пример, ClientDataSet (любой ДатаСет), в design-time по двойному клику на компоненте вызывается окно редактирования компонента, в котором мы можем добавлять поля (объекты-поля). При добавлении поля оно появляется как новый объект формы, на которой размещен компонент.
Прошу высказываться тем, кто это делал или знает источник, где ИМЕННО эта проблема описывается и разрешается :)).
P.S. Я дошел до момента вызова окна редактирования компонента. Коллекции - не то!
-
> Коллекции - не то!
Ошибаетесь. Именно то. По даблклику вызывается метод Edit (точнее ExecuteVerb(0)) редактора компонента. Зарегистрируйте свой редактор, со своим окном.
TMyComponentEditor = class(TComponentEditor)
function GetVerb(Index: integer): string; override; function GetVerbCount: integer; override; procedure ExecuteVerb(Index: integer); override; end;
procedure TMyComponentEditor.ExecuteVerb(Index: integer);
begin
case Index of
0: ShowMyWindowEditorComponent;
1: ;
else inherited ExecuteVerb(Index)
end;
end;
procedure Register;
begin
RegisterComponents('MyComponentPage',TMyComponent);
RegisterComponentEditor(TMyComponent,TMyComponentEditor);
end;
-
Я написал, что вызов окна по дабл-клику сделан. К стати, работает и без определения ExecuteVerb.
Мне нужен механизм как после нажатия, наприме, кнопки Add, создается объект, который прописывается в текстовом редакторе, как обычные компоненты при броске.
Я предполагаю, что это происходит автоматически при создании компонента(объекта) в design-time при этом Owner - Application.
-
Попробуй так: TMyComponent=class(TComponent)
....
constructor TMyComponent.Create(AOwner:TComponent);
begin
ChildComponent:=TChildComponent.Create(AOwner);
...
end;
-
Напрмер так
Designer.CreateComponent(TButton,Designer.Root,ALeft,ATop,AWidth,AHeight);
-
Естественно, нужно зарегестрировать дочерний компонент через RegisterNoIcon. Иначе они появится на форме. Кроме того должны быть использованы методы связаные с FreeNotification. Иначе при удалении дочернего компонента могут возникнуть немалые проблемы.
-
to Наиль Это, вроде, не в ту степь.
to DimaBr Мне не надо создавать кнопку, мне нужно по нажатию кнопки созавать объект.
Смотрите, как работает ДатаСет в design-time при двойном нажатии на нем. Тогда поймете о чем я говорю.
-
> Мне не надо создавать кнопку, мне нужно по нажатию кнопки > созавать объект.
Вы чо, совсем или частично...... Создавайте ваш компонент Designer.CreateComponent(TMyComponent,Designer.Root,ALeft,ATop,AWidth,AHeight);
-
Буду пробовать, но грубить не надо!
-
А чей Designer нужно брать?
-
Может, кто-то ответит?
Кто может посоветовать источник, который описывает работу с Designer.
А то я нашел, что есть два его типа IDesigner и IDesignerHook. И именно второй имеет процедуру CreateComponent. И надо разобратся, что к чему.
-
Решил я задачю. В моем случаи нужны были такие строки: // создаем экземпляр компонента SLCItem := TSLCItem.Create(FOwnerComponent.Root); // даем ему имя как имя SLCItem+порядковый номер (это делает UniqueName) TComponent(SLCItem).Name := FOwnerComponent.UniqueName('SLCItem');
FOwnerComponent - это Designer, который передается из проц. Edit редатора компонента.
Загвоздка в том что у меня TSLCItem - это компонент, который не добавляется в палитру компонентов (т.е. RegisterNoIcon), поэтому Designer.CreateComponent(TMyComponent,Designer.Root,ALeft,ATop,AWidth,AHeight); здесь не подходит.
-
Так как Вы собираеесь создавать компонент из дизайнера компонента, то для вызова окна дезайнера нужно передать указатель на интерфейс дизайнера (IDesigner)
procedure TMyComponentEditor.ExecuteVerb(Index: Integer);
begin
case Index of
0: ShowMyComponentsEditor(Designer);
else inherited;
end;
end; Тогда, используя интерфейс дизайнера и создаёте компонент. А Designer.CreateComponent создаёт любой компонент, хоть иконный, хоть нет.
-
Именно так я сделал.
Проверено, Designer.CreateComponent создает компоненты С ЗАПИСЬЮ НОВОГО ОБЪЕКТА в текстовый редактор, только для компонентов, которые есть на палитре компонентов.
Если же компонент зарегистрирован через RegisterNoIcon, то приведенная строка не работает.
Если она у Вас работает и с такими компонентами, то это баг. Так как в хелпе написано, что компоненты зарегистрированные через RegisterNoIcon должны ЯВНО создаваться через Create. Что я и сделал, и все заработало.
-
Что я не делаю у меня дочерний компонент не хочет создаваться внутри компонента с которого я вызываю дизайнер компонента. вот создание компонента из дизайнера:
S:= TSpecColumnNumber.Create(Designer.Root);
S.Name:= 'SpecColumnNumber1blabla';
Designer.Modified;
Designer - это ссылка дизайнера компонента если просмотреть форму как текст, то получаем следующее:
....
object DocumentSpecification1: TDocumentSpecification
Caption = 'бла-бла'
Actual = False
end
object SpecColumnNumber1blabla: TSpecColumnNumber
Width = 102572808
end
...
а должно быть так:
...
object DocumentSpecification1: TDocumentSpecification
Caption = 'бла-бла'
Actual = False
object SpecColumnNumber1blabla: TSpecColumnNumber
Width = 102572808
end
end
...
Еще, если я создал компонент, созхранил форму, закрыл, а затем открыл, то IDE выводит ошибку Error Reading Form "Invalid class typecast. Ingore the error and continue. ....."
-
-
-
2 DimaBr где ж Вы раньше были! Все получилось! :-)))))
-
Там же где и счас. Просто это уже обсуждалось неоднократно и очередной новый компонентописатель опять же наступает на одни и теже грабли.
-
Ай! 2 DimaBar: > Дизайнер тут не причём, опять те же грабли. > ВНИМАТЕЛЬНО изучайте GetChildren !!! > Вот разбор полётов с готовым примером. > http://pda.delphimaster.net/?id=1162824958&n=12
Произошла ошибка: Не найдена ветка № 1162824958, возможно она была удалена или перенесена в другой форум.
|