Форум: "Компоненты";
Текущий архив: 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.037 c