Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.11.06;
Скачать: CL | DM;

Вниз

Как создать компонент, состоящий из нескольких компонет?   Найти похожие ветки 

 
Артем К.   (2005-02-04 08:41) [0]

Здравствуйте, Мастера!

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

Как сделать, чтобы в Object TreeView можно было бы выбирать  каждый из этих компонентов, редактировать свойства, методы и т.д.
Ну типа как у PageControla каждую страничку можно отдельно редактировать.


 
Rule ©   (2005-02-04 08:58) [1]

попробуй чеерз TCollection
http://delphikingdom.ru/asp/viewitem.asp?catalogID=215


 
Артем К.   (2005-02-07 09:01) [2]

а разве TPageControl основан на коллекциях, по-моему НЕТ!

Надо как-то иначе, вот только как?


 
-=SS=- ©   (2005-02-07 09:37) [3]

В секции приватэ абъявляешь нужные тебе компоненты, а в секции публик все нужные тебе проперти


 
Юрий Зотов ©   (2005-02-07 12:31) [4]

> -=SS=- ©   (07.02.05 09:37) [3]
Пожалуйста, проверьте свой совет сами. Есть опасение, что одних объявлений будет маловато, а секция public здесь вообще ни при чем.

> Артем К.   (04.02.05 08:41)

1. Компонент-контейнер должен содержать список внутренних компонентов (у TPageControl это поле FPages) и методы создания/удаления внутреннего компонента (с его добавлением в этот список или удалением из него - аналоги InsertPage и RemovePage).

2. Для автоматического удаления внутренних компонентов (в том числе, из списка) в контейнере потребуется замещение деструктора и Notification.

3. В контейнере надо заместить методы GetChildren и SetChildOrder (по аналогии с TPageControl).

4. Пишем редактор компонента, в котором замещаем методы GetVerbCount, GetVerb и ExecuteVerb. В итоге получаем пункты меню, аналогичные New Page, Next Page и пр. у TPageControl.


 
Артем К.   (2005-02-07 14:31) [5]

> Юрий Зотов ©   (07.02.05 12:31)

Сделал, все как Вы сказали... Подскажите пожалуйста, как теперь связать элемент меню (New Page) ComponentEditora с созданием новой странички...

Заранее спасибо!


 
Юрий Зотов ©   (2005-02-07 16:01) [6]

procedure TMyComponentEditor.ExecuteVerb(Index: integer);
begin
 with Component as TMyComponent do
 case Index of
   0: InsertItem;
   1: NextItem;
   2: PrevItem;
   3: RemoveItem
 end
end;


 
Артем К.   (2005-02-07 16:08) [7]

У меня процедурка такая

procedure TMyComponent.InsertPage(Value: TMyPage);
begin
Pages.Add(TMyPage);
Value.PageControl := Self;
end;


как сделать, так что ли?


procedure TMyComponentEditor.ExecuteVerb(Index: integer);
var
Page: TMyPage;
begin
with Component as TMyComponent do
case Index of
  0: InsertPage(Page);
end
end;


 
Артем К.   (2005-02-07 16:10) [8]

описался... я
процедура такая

procedure TMyComponent.InsertPage(Value: TMyPage);
begin
Pages.Add(Value);
Value.PageControl := Self;
end;


 
Юрий Зотов ©   (2005-02-07 16:56) [9]

procedure TMyComponentEditor.ExecuteVerb(Index: integer);
begin
 with Component as TMyComponent do
 case Index of
   0: InsertPage(TMyPage.Create(...));
 end
end;


 
Артем К.   (2005-02-10 10:03) [10]

>> Юрий Зотов

Сделал все, как Вы сказали, но у меня ничего не получилось, не могу разобраться где ошибка, помогите пожалуйста

Вот весь исходный код моих мытарств:


 TKAPage = class (TCustomControl);

 TKAPageControl = class (TCustomControl)
   private
     thePages: TList;
     procedure InsertPage(Page: TKAPage);
     procedure RemovePage(Page: TKAPage);
   protected
     procedure GetChildren(Proc: TGetChildProc;
                           Root: TComponent); override;    
   public
     constructor Create(Owner: TComponent); override;
     destructor Destroy; override;
 end;

 TKAPageControlEditor = class(TComponentEditor)
   procedure ExecuteVerb(Index: integer); override;
   function GetVerb(Index: integer): string; override;
   function GetVerbCount: integer; override;
 end;

...

 procedure Register;
 begin
   RegisterComponents("KAComponents",
                      [TKAPageControl]);
   RegisterComponentEditor(TKAPageControl,
                           TKAPageControlEditor);
 end;

 procedure TKAPageControl.InsertPage(Page: TKAPage);
 begin
   thePages.Add(Page);
 end;

 procedure TKAPageControl.RemovePage(Page: TKAPage);
 begin
   thePages.Remove(Page);
 end;

 procedure TKAPageControl.GetChildren(Proc: TGetChildProc;
                                      Root: TComponent);
 var
   i: integer;
 begin
   for i := 0 to thePages.Count - 1 do
     Proc(TComponent(thePages[i]));
 end;

 constructor TKAPageControl.Create(Owner: TComponent);
 begin
   inherited Create(Owner);
   thePages := TList.Create;
   Width := 300;
   Height := 200;
 end;

 destructor TKAPageControl.Destroy;
 begin
   thePages.Free;
   inherited Destroy;
 end;

...

 procedure TKAPageControlEditor.ExecuteVerb(Index: Integer);
 begin
   with (Component as TKAPageControl) do
     case Index of
       0: InsertPage(TKAPage.Create((Component as
                     TKAPageControl)));
     end;
 end;

 function TKAPageControlEditor.GetVerb(Index: Integer): string;
 begin
   case Index of
     0: Result := "New page";
   end;
 end;

 function TKAPageControlEditor.GetVerbCount: Integer;
 begin
   Result := 1;
 end;


Заранее, спасибо!


 
Юрий Зотов ©   (2005-02-11 00:43) [11]


unit KAPageControl;

interface

uses
 Classes, Controls, ExtCtrls, DesignIntf, DesignMenus, DesignEditors;

type
 TKAPage = class(TPanel)
 public
   constructor Create(AOwner: TComponent); override;
 published
   property Align default alBottom;
 end;

 TKAPageControl = class(TCustomControl)
 private
   FPages: TList;
   function GetPageCount: integer;
   function GetPages(Index: integer): TKAPage;
 protected
   procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
   procedure Notification(AComponent: TComponent; Operation: TOperation); override;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   procedure AddPage;
   procedure RemovePage(Page: TKAPage); overload;
   procedure RemovePage(Index: integer); overload;
   function FindPage(Page: TKAPage): integer;
   procedure Clear;
   property PageCount: integer read GetPageCount;
   property Pages[Index: integer]: TKAPage read GetPages;
 published
   property Height default 200;
   property Width default 300;
 end;

 TKAPageControlEditor = class(TComponentEditor)
   procedure ExecuteVerb(Index: integer); override;
   function GetVerb(Index: integer): string; override;
   function GetVerbCount: integer; override;
   procedure PrepareItem(Index: Integer; const AItem: IMenuItem); override;
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents("KAComponents", [TKAPageControl]);
 RegisterComponentEditor(TKAPageControl, TKAPageControlEditor)
end;

{ TKAPage }

constructor TKAPage.Create(AOwner: TComponent);
begin
 inherited;
 Align := AlBottom
end;

{ TKAPageControl }

procedure TKAPageControl.AddPage;
begin
 FPages.Add(TKAPage.Create(Owner));
 Pages[PageCount - 1].Parent := Self
end;

procedure TKAPageControl.RemovePage(Page: TKAPage);
begin
 if FPages.Remove(Page) >= 0 then
   Page.Free
end;

procedure TKAPageControl.RemovePage(Index: integer);
begin
 RemovePage(Pages[Index])
end;

procedure TKAPageControl.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
 i: integer;
begin
 for i := 0 to PageCount - 1 do
   Proc(Pages[i])
end;

constructor TKAPageControl.Create(AOwner: TComponent);
begin
 inherited;
 FPages := TList.Create;
 SetBounds(Left, Top, 300, 200)
end;

destructor TKAPageControl.Destroy;
begin
 Clear;
 FPages.Free;
 inherited
end;

function TKAPageControl.GetPageCount: integer;
begin
 Result := FPages.Count
end;

procedure TKAPageControl.Notification(AComponent: TComponent; Operation: TOperation);
var
 Index: integer;
begin
 inherited;
 if (Operation = opRemove) and (AComponent is TKAPage) and not (csDestroying in ComponentState) then
 begin
   Index := FindPage(TKAPage(AComponent));
   if Index >= 0 then
     FPages.Delete(Index)
 end
end;

function TKAPageControl.GetPages(Index: integer): TKAPage;
begin
 Result := TKAPage(FPages[Index])
end;

procedure TKAPageControl.Clear;
var
 i: integer;
begin
 for i := PageCount - 1 downto 0 do
   RemovePage(i)
end;

function TKAPageControl.FindPage(Page: TKAPage): integer;
var
 i: integer;
begin
 Result := -1;
 for i := 0 to PageCount - 1 do
   if Pages[i] = Page then
   begin
     Result := i;
     Break
   end
end;

{ TKAPageControlEditor }

procedure TKAPageControlEditor.ExecuteVerb(Index: Integer);
begin
 with Component as TKAPageControl do
   case GetVerbCount - Index of
     1: RemovePage(PageCount - 1);
     2: begin
          AddPage;
          Pages[PageCount - 1].Name := Designer.UniqueName(Name + "Page")
        end
     else
       inherited
   end
end;

function TKAPageControlEditor.GetVerb(Index: Integer): string;
begin
 case GetVerbCount - Index of
   1: Result := "Remove last page";
   2: Result := "Add new page"
   else
     Result := inherited GetVerb(Index)
 end
end;

function TKAPageControlEditor.GetVerbCount: Integer;
begin
 Result := inherited GetVerbCount + 2
end;

procedure TKAPageControlEditor.PrepareItem(Index: Integer; const AItem: IMenuItem);
begin
 inherited;
 AItem.Enabled := (GetVerbCount - Index <> 1) or ((Component as TKAPageControl).PageCount > 0)
end;

initialization

 RegisterClass(TKAPage)

finalization

 UnRegisterClass(TKAPage)

end.


 
Артем К.   (2005-02-11 03:08) [12]

>> Юрий Зотов
Спасибо Вам Большое...

Почему то когда я нажимаю в меню "New page", то страничка добавляется не сразу, а после того, как ясниму выделение с PageControla...


initialization

RegisterClass(TKAPage)

finalization

UnRegisterClass(TKAPage)


Зачем нужна такая конструкция?

Заранее спасибо!


 
Юрий Зотов ©   (2005-02-11 10:04) [13]

> Артем К.   (11.02.05 03:08) [12]

> когда я нажимаю в меню "New page", то страничка добавляется
> не сразу, а после того, как ясниму выделение с
> PageControla...

Значит, что-то Вы переделали. Чтобы сказать точнее, нужно знать, что именно.

> Зачем нужна такая конструкция?

Без нее при загрузке DFM получаем сообщение "Class not found".

P.S.
Надо добавить вот что - не рассматривайте этот код, как абсолютно законченный. Хоть он и полностью рабочий, но все же это еще скелет, а не готовый компонент. На этот скелет нужно еще нарастить функциональность, определяемую назначением компонента (например, переключение страниц).


 
Артем К.   (2005-02-11 13:09) [14]

Я добавил такую штуку в обработчик ExecuteVerb:  Designer.Modified;
Теперь при добавлении страницы все правильно обновляется сразу.

Возникла еще одна проблема... для TKAPage я сделал:

ControlStyle := ControlStyle + [csAcceptsControls];

При размещении компонентов на странице, в Design-тайме они показываются, а вот в Run-тайме нет... В чем может быть ошибка?


 
Юрий Зотов ©   (2005-02-11 13:15) [15]

> Артем К.   (11.02.05 13:09) [14]

Видимо, владелец страниц - не форма. Приведите код.


 
Артем К.   (2005-02-11 13:57) [16]


 procedure TKAPageControl.AddPage;
 begin
   thePages.Add(TKAPage.Create(Owner));
   Pages[PageCount - 1].Parent := Self;
   Pages[PageCount - 1].Caption := "Page" + IntToStr
                                   (PageCount);
 end;


 
Артем К.   (2005-02-13 11:11) [17]

Ну так как быть?


 
Артем К.   (2005-02-15 14:29) [18]

Удалено модератором
Примечание: Не надо спамить.



Страницы: 1 вся ветка

Текущий архив: 2005.11.06;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.048 c
2-1129346563
antoxa2005
2005-10-15 07:22
2005.11.06
Подскажите, если кто знает. Как добавить записи в таблицуБД MySQL


4-1125398360
Shpil
2005-08-30 14:39
2005.11.06
Получение списка устройств


2-1129298933
roma40
2005-10-14 18:08
2005.11.06
интернет


1-1129200448
BFG9k
2005-10-13 14:47
2005.11.06
Dephi стирает {$IFDEF}


2-1129444064
Бродяга_
2005-10-16 10:27
2005.11.06
Как в DBGrid перебрать все строки