2008-12-17 7 views
6

J'ai écrit un contrôle personnalisé, qui a plusieurs sous-panneaux. Je veux que ces sous-panneaux acceptent tous les contrôles supplémentaires déposés sur eux lors de la conception.Comment créer un contrôle personnalisé avec un sous-panneau qui accepte d'autres contrôles au moment du design?

Malheureusement, tout contrôle qui est abandonné au moment du design finit sur mon contrôle personnalisé, pas sur les panneaux. Cela montre en particulier si j'essaie d'abandonner une étiquette: Les points bleus de l'étiquette sont montrés, mais ce n'est pas la légende et si je désélectionne l'étiquette, elle n'est plus visible du tout.

code simplifié (un seul panneau secondaire):

type 
    TMyContainer = class(TPanel) 
    p_SubPanel: TPanel; 
    public 
    constructor Create(_Owner: TComponent); override; 
    end; 

    constructor TMyContainer.Create(_Owner: TComponent); 
    begin 
    inherited; 
    p_SubPanel := TPanel.Create(Self); 
    p_SubPanel.Parent := Self; 
    p_SubPanel.Align := alClient; 
    end; 

ce que je fais mal ici?

(au cas où il importe: J'utilise Delphi 2007)

[modifier]

Je suis maintenant résolu différemment. Le composant ne contient plus de panneaux mais fait référence à des panneaux externes. Cela le rend beaucoup plus flexible, mais à la baisse, il n'est plus aussi intuitif à utiliser.

Je voudrais toujours savoir comment accomplir ce que j'ai décrit à l'origine. N'y a-t-il pas quelque part un composant open source qui fait cela, donc je peux étudier le code source?

Répondre

1

Je ne peux pas dire à partir des détails, mais définissez-vous le parent de l'étiquette à votre sous-panneau? Si c'est au moment de la conception, vous devrez peut-être écrire du code dans votre composant principal (par exemple le conteneur dans lequel se trouvent vos panneaux), pour déterminer quel sous-panneau accepte le composant et définir la propriété parent des étiquettes sur ce sous-panneau.

Je suis sûr que la méthode de notification est appelée lorsqu'un composant est ajouté ou supprimé d'un autre composant, cela devrait vous aider à trouver où vous devez placer le code.

2

C'est une bonne question. Vous pouvez autoriser votre TWinControl personnalisé à supprimer d'autres contrôles au moment de la conception en ajoutant csAcceptControls à la propriété ControlStyle de vos contrôles.

constructor TMyContainer.Create(AOwner: TComponent); 
begin 
    inherited; 
    ControlStyle := ControlStyle + [csAcceptControls]; 
end; 

Mais en essayant de nous en sortir, j'ai eu peu de succès avec être en mesure de déposer des contrôles sur un panneau secondaire dans un contrôle personnalisé. L'ajout de csAcceptControls à ControlStyle d'un sous-panneau n'est pas suffisant. Le cloest j'ai obtenu est un hack pour convaincre le sous-panneau, il est d'être conçu comme ceci:

type 
    TGiveMeProtected_Component = class(TComponent); 

procedure TMyContainer.Create(AOwner: TComponent); 
begin 
    FSubPanel := TPanel.Create(Self); 
    TGiveMeProtected_Component(FSubPanel).SetDesigning(True, True); 
end; 

En utilisant ce code, vous pouvez déposer des contrôles sur le panneau secondaire, mais cela signifie que vous pouvez également sélectionner le sous panneau, modifiez ses propriétés et même supprimez-le que vous ne voulez certainement pas. Désolé je ne pourrais pas trouver la réponse, j'aimerai toujours savoir si vous vous en sortez. :)

0

Je l'ai fait, mais j'ai fini par remplacer les contrôles par des panneaux réguliers qui seraient montrés/cachés si nécessaire. Au lieu de descendre de TPanel, mes contrôles descendent de TCustomControl. Je ne pense pas que je pourrais le faire fonctionner en descendant de TPanel mais je ne me souviens plus du problème.

Le contrôle conteneur:

TPageControl = class(TCustomControl) 
private 
    PageList:TObjectList; // To hold references to all sub-pages for easy access. 
end; 

constructor TPageControl.Create(AOwner: TComponent); 
begin 
    inherited; 
    ControlStyle := ControlStyle + [csAcceptsControls]; 
    PageList := TObjectList.Create; 
    PageList.OwnsObjects := false; 
end; 

destructor TVstPageControl.Destroy; 
begin 
    PageList.Free; 
    inherited; 
end; 

procedure TPageControl.NewPage; 
var 
    Page:TPage; 
begin 
    Page := TPage.Create(Self.Owner); 
    Page.Parent := Self; 
    Page.Align := alClient; 

    PageList.Add(Page); 
end; 

procedure TPageControl.DeletePage(Index:integer); 
var 
    Page:TPage; 
begin 
    Page := PageList[Index] as TPage; 
    Page.Free; 
    PageList.Delete(Index); 
end; 

La page/commande de sous-panneau:

TVstPage = class(TCustomControl) 
public 
    constructor Create(AOwner: TComponent); override; 
end; 

constructor TPage.Create(AOwner: TComponent); 
begin 
    inherited; 
    ControlStyle := ControlStyle + [csAcceptsControls]; 
end; 
Questions connexes