Конференция "Компоненты" » Создание дочерних объектов в design-time [D6]
 
  • AlexPotter © (18.08.06 11:18) [0]
    Собственно вопрос такой:
     какой механизм создания дочерних объектов в design-time?

     Пример, ClientDataSet (любой ДатаСет),  в design-time по двойному клику на компоненте вызывается окно редактирования компонента, в котором мы можем добавлять поля (объекты-поля).
    При добавлении поля оно появляется как новый объект формы, на которой размещен компонент.

    Прошу высказываться тем, кто это делал или знает источник, где ИМЕННО эта проблема описывается и разрешается :)).

    P.S.
      Я дошел до момента вызова окна редактирования компонента.
      Коллекции - не то!
  • DimaBr (18.08.06 12:38) [1]

    > Коллекции - не то!

    Ошибаетесь. Именно то. По даблклику  вызывается метод Edit (точнее ExecuteVerb(0)) редактора компонента. Зарегистрируйте свой редактор, со своим окном.


    TMyComponentEditor = class(TComponentEditor)
     function GetVerb(Index: integer): string; override; // возвращает название пунктов PopupMenuдля комронента
     function GetVerbCount: integer; override; // возвращает количество этих пунктов
     procedure ExecuteVerb(Index: integer); override; // действие при выборе Index- пункта
    end;

    procedure TMyComponentEditor.ExecuteVerb(Index: integer);
    begin
     case Index of
        0: ShowMyWindowEditorComponent;
        1: ;
     else inherited ExecuteVerb(Index)
     end;{case}
    end;

    procedure Register;
    begin
     RegisterComponents('MyComponentPage',TMyComponent);
     RegisterComponentEditor(TMyComponent,TMyComponentEditor);
    end;

  • AlexPotter © (18.08.06 13:26) [2]
    Я написал, что вызов окна по дабл-клику сделан.
    К стати, работает и без определения ExecuteVerb.

    Мне нужен механизм как после нажатия, наприме, кнопки Add, создается объект, который прописывается в текстовом редакторе, как обычные компоненты при броске.

    Я предполагаю, что это происходит автоматически при создании компонента(объекта) в design-time при этом Owner - Application.
  • Наиль © (18.08.06 13:53) [3]
    Попробуй так:
    TMyComponent=class(TComponent)
    ....
    constructor TMyComponent.Create(AOwner:TComponent);
    begin
    ChildComponent:=TChildComponent.Create(AOwner);
    ...
    end;

  • DimaBr (18.08.06 13:58) [4]
    Напрмер так

    Designer.CreateComponent(TButton,Designer.Root,ALeft,ATop,AWidth,AHeight);

  • Наиль © (18.08.06 14:08) [5]
    Естественно, нужно зарегестрировать дочерний компонент через RegisterNoIcon. Иначе они появится на форме. Кроме того должны быть использованы методы связаные с FreeNotification. Иначе при удалении дочернего компонента могут возникнуть немалые проблемы.
  • AlexPotter © (18.08.06 14:09) [6]
    to Наиль
     Это, вроде, не в ту степь.

    to DimaBr
     Мне не надо создавать кнопку, мне нужно по нажатию кнопки созавать объект.

    Смотрите, как работает ДатаСет в design-time при двойном нажатии на нем. Тогда поймете о чем я говорю.
  • DimaBr (18.08.06 15:17) [7]

    > Мне не надо создавать кнопку, мне нужно по нажатию кнопки
    > созавать объект.

    Вы чо, совсем или частично...... Создавайте ваш компонент
    Designer.CreateComponent(TMyComponent,Designer.Root,ALeft,ATop,AWidth,AHeight);
  • AlexPotter © (18.08.06 15:32) [8]
    Буду пробовать, но грубить не надо!
  • AlexPotter © (18.08.06 17:31) [9]
    А чей Designer нужно брать?
  • AlexPotter © (18.08.06 23:23) [10]
    Может, кто-то ответит?

    Кто может посоветовать источник, который описывает работу с Designer.

    А то я нашел, что есть два его типа IDesigner и IDesignerHook.
    И именно второй имеет процедуру CreateComponent.

    И надо разобратся, что к чему.
  • AlexPotter © (19.08.06 13:04) [11]
    Решил я задачю.
     В моем случаи нужны были такие строки:
     
     // создаем экземпляр компонента
     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); здесь не подходит.
  • DimaBr (21.08.06 08:54) [12]
    Так как Вы собираеесь создавать компонент из дизайнера компонента, то для вызова окна дезайнера нужно передать указатель на интерфейс дизайнера (IDesigner)

    procedure TMyComponentEditor.ExecuteVerb(Index: Integer);
    begin
     case Index of
       0: ShowMyComponentsEditor(Designer);
     else inherited;
     end;{case}
    end;


    Тогда, используя интерфейс дизайнера и создаёте компонент.
    А Designer.CreateComponent создаёт любой компонент, хоть иконный, хоть нет.
  • AlexPotter © (28.08.06 10:52) [13]
    Именно так я сделал.

    Проверено, Designer.CreateComponent создает компоненты С ЗАПИСЬЮ НОВОГО ОБЪЕКТА в текстовый редактор, только для компонентов, которые есть на палитре компонентов.

    Если же компонент зарегистрирован через RegisterNoIcon, то приведенная строка не работает.

    Если она у Вас работает и с такими компонентами, то это баг. Так как в хелпе написано, что компоненты зарегистрированные через RegisterNoIcon должны ЯВНО создаваться через Create. Что я и сделал, и все заработало.
  • Евгений1111 (28.12.06 14:44) [14]
    Что я не делаю у меня дочерний компонент не хочет создаваться внутри компонента с которого я вызываю дизайнер компонента.

    вот создание компонента из дизайнера:


     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. ....."
  • DimaBr (28.12.06 15:27) [15]
    Дизайнер тут не причём, опять те же грабли.  
    ВНИМАТЕЛЬНО изучайте GetChildren !!!
    Вот разбор полётов с готовым примером.
    http://pda.delphimaster.net/?id=1162824958&n=12
  • DimaBr (28.12.06 15:28) [16]
    А вот Invalid class typecast
    http://pda.delphimaster.net/?id=1163604047&n=12
  • Евгений1111 (28.12.06 17:34) [17]
    2 DimaBr
    где ж Вы раньше были! Все получилось! :-)))))
  • DimaBr (29.12.06 09:21) [18]
    Там же где и счас. Просто это уже обсуждалось неоднократно и очередной новый компонентописатель опять же наступает на одни и теже грабли.
  • Женя (17.07.09 14:52) [19]
    Ай!

    2 DimaBar:


    > Дизайнер тут не причём, опять те же грабли.  
    > ВНИМАТЕЛЬНО изучайте GetChildren !!!
    > Вот разбор полётов с готовым примером.
    > http://pda.delphimaster.net/?id=1162824958&n=12


    Произошла ошибка:

    Не найдена ветка № 1162824958, возможно она была удалена или перенесена в другой форум.
 
Конференция "Компоненты" » Создание дочерних объектов в design-time [D6]
Есть новые Нет новых   [120271   +35][b:0][p:0.002]