Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];

Вниз

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

 
Артем К.   (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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.044 c
14-1129567066
ArtemESC
2005-10-17 20:37
2005.11.06
Эффективный алгоритм


9-1118910515
Xenon
2005-06-16 12:28
2005.11.06
Вопросик по PD


3-1127946719
turonix
2005-09-29 02:31
2005.11.06
Как через ADO узнать является ли текущее поле Primery Key


3-1127884765
Barmaglot
2005-09-28 09:19
2005.11.06
Правильно-ли представлена связь между таблицами?


4-1125602005
Vjacheslav
2005-09-01 23:13
2005.11.06
Библиотека winlite





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский