2010-11-22 3 views
6

J'ai créé un contrôle personnalisé TOuterControl qui est le parent de plusieurs TInnerControls.Empêche l'IDE Delphi de créer des icônes de composants au moment du design

Tout fonctionne correctement, sauf que l'IDE crée des icônes pour chaque TInnerControl enfant (InnerControl1 et InnerControl2 dans la capture d'écran). Comment empêcher l'IDE de générer les icônes?

alt text

unit TestControl; 

interface 

Procedure Register; 

implementation 

Uses 
    Classes, 
    Controls, 
    SysUtils, 
    DesignEditors, 
    DesignIntf, 
    VCLEditors; 

Type 

TOuterControl = Class; 

TInnerControl = Class(TComponent) 
Protected 
    FOuterControl : TOuterControl; 

    function GetParentComponent: TComponent; Override; 
    Function HasParent : Boolean; Override; 
    procedure SetParentComponent     (Value: TComponent); Override; 
End; 

TOuterControl = Class(TCustomControl) 
Protected 
    FInnerControls : TList; 

    Procedure Paint; Override; 
Public 
    Constructor Create(AOwner : TComponent); Override; 
    Procedure AddInnerControl(AInnerControl : TInnerControl); 
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; 
End; 

TOuterControlEditor = Class(TDefaultEditor) 
Public 
    Procedure ExecuteVerb(Index : Integer);   Override; 
    Function GetVerb (Index : Integer) : String; Override; 
    Function GetVerbCount  : Integer;   Override; 
End; 

procedure TOuterControl.AddInnerControl(AInnerControl: TInnerControl); 
begin 
    AInnerControl.FOuterControl := Self;; 
    FInnerControls.Add(AInnerControl); 
    Invalidate; 
end; 

constructor TOuterControl.Create(AOwner: TComponent); 
begin 
    inherited; 

    FInnerControls := TList.Create; 
end; 

procedure TOuterControl.GetChildren(Proc: TGetChildProc; Root: TComponent); 
var 
    I : Integer; 
begin 
    inherited; 

    For I := 0 To FInnerControls.Count - 1 Do 
     Proc(FInnerControls[I]); 
end; 

procedure TOuterControl.Paint; 
begin 
    inherited; 

    Canvas.FillRect(ClientRect); 
    Canvas.TextOut(0,0, Format('Inner Control Count = %d', [FInnerControls.Count])); 
end; 

function TInnerControl.GetParentComponent: TComponent; 
begin 
    Result := FOuterControl; 
end; 

function TInnerControl.HasParent: Boolean; 
begin 
    Result := True; 
end; 

procedure TInnerControl.SetParentComponent(Value: TComponent); 
begin 
    If Value Is TOuterControl Then 
     If FOuterControl <> Value Then 
    Begin 
     FOuterControl := TOuterControl(Value); 
     FOuterControl.AddInnerControl(Self); 
    End; 
end; 

procedure TOuterControlEditor.ExecuteVerb(Index: Integer); 
Var 
    OuterControl : TOuterControl; 
    InnerControl : TInnerControl; 
begin 
    inherited; 

    OuterControl := TOuterControl(Component); 

    If Index = 0 Then 
    Begin 
     InnerControl := TInnerControl.Create(OuterControl.Owner); 
     OuterControl.AddInnerControl(InnerControl); 
    End; 
end; 

function TOuterControlEditor.GetVerb(Index: Integer): String; 
begin 
    Result := 'Add Inner'; 
end; 

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

Procedure Register; 
Begin 
    RegisterComponents('AA', [TOuterControl]); 
    RegisterComponentEditor(TOuterControl, TOuterControlEditor); 
End; 


Initialization 
    Classes.RegisterClasses([TInnerControl]); 

end. 
+3

Il semble que vous réinventiez 'TCollection'. Faites descendre les "contrôles" internes de 'TCollectionItem', définissez un petit descendant' TOwnedCollection' pour le contrôle externe, et toutes vos tâches de gestion au moment du design seront résolues. –

+0

L'utilisation de TCollectionItem et TOwnedCollection n'a pas de sens dans ma situation, le code que j'ai posté est un exemple réduit. – Frank

+0

Pourquoi cela n'a-t-il pas de sens? Qu'est-ce que vous essayez d'accomplir que TCollection/TCollectionItem ne peut pas gérer exactement? –

Répondre

7

Vous pouvez les empêcher de appeaing sur la forme avec:

RegisterNoIcon([TInnerControl]); 

Plus d'info sur RegisterNoIcon se trouve à http://docwiki.embarcadero.com/VCL/e/index.php/Classes.RegisterNoIcon

Il est un peu déroutant ayant des classes avec un nom qui se terminent par « Control » ce ne sont pas des contrôles visuels normaux cependant.

+0

+1 pour ne pas mentionner la phrase "RegisterNoIcon" qui prête également à confusion - parce que nous n'inscrivons aucune icône, mais nous enregistrons sans l'icône d'une palette de composants. RegisterWithoutIcon ou même RegisterComponentsWithoutIcon aurait été plus auto-documenté. – TheBlastOne

+0

En tant que personne qui a voté cette réponse pour * ne * pas mentionner le nom confus, @ TheBlast, vous parlez beaucoup sur le nom confus. –

+1

SetSubComponent() est l'approche correcte. RegisterNoIcon() peut avoir un effet secondaire utile (je ne suis pas sûr que c'est le cas, je n'ai pas testé) mais techniquement, ne fait pas ce qui est nécessaire (sauf par accident, auquel cas il peut légitimement cesser de le faire à un moment donné). – Deltics

4

Lorsque vous créez les contrôles internes, vous leur dites que leur propriétaire est la forme (le propriétaire du contrôle externe). Par conséquent, la forme les attire, tout comme elle attire tous les autres composants qu'elle possède. Vous voulez probablement que le contrôle externe possède les contrôles internes.

5

Si TInnerControl est destiné à être utilisé uniquement dans un TOuterControl, vous devez appeler SetSubComponent (True) pendant/après la création de TInnerControl.

+1

Je ne sais pas pourquoi cela n'a pas été accepté comme la bonne réponse. C'est la bonne réponse. Je peux seulement penser que RegisterNoIcon peut avoir un effet secondaire utile (je n'ai pas testé pour voir si c'est le cas). – Deltics

Questions connexes