2010-11-22 12 views
6

Ho creato un controllo personalizzato TOuterControl che è il padre di più TInnerControls.Impedisce a Delphi IDE di creare le icone dei componenti in fase di progettazione

Tutto funziona correttamente, tranne che l'IDE sta creando icone per ogni bambino TInnerControl (InnerControl1 e InnerControl2 nello screenshot). Come posso evitare che l'IDE generi le icone?

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

Sembra che tu stia reinventando 'TCollection'. Fai in modo che i "controlli" interni scendano da 'TCollectionItem', definisci un piccolo discendente' TOwnedCollection' per il controllo esterno e tutte le attività di gestione in fase di progettazione saranno risolte. –

+0

L'uso di TCollectionItem e TOwnedCollection non ha senso nella mia situazione, il codice che ho postato è un esempio ridotto. – Frank

+0

Perché non ha senso? Cosa stai cercando di ottenere che TCollection/TCollectionItem non possa gestire esattamente? –

risposta

7

È possibile impedire appeaing sul modulo con:

RegisterNoIcon([TInnerControl]); 

Maggiori informazioni RegisterNoIcon può essere trovato alla http://docwiki.embarcadero.com/VCL/e/index.php/Classes.RegisterNoIcon

E 'un po' di confusione con le classi con un nome che terminano con "Control" che non sono normali controlli visivi però.

+0

+1 per non aver menzionato la frase "RegisterNoIcon" anche perché non siamo "registrati senza icona", ma registriamo senza un'icona della tavolozza dei componenti. RegisterWithoutIcon o anche RegisterComponentsWithoutIcon sarebbe stato più auto-documentante. – TheBlastOne

+0

Come qualcuno che ha votato questa risposta per * non * menzionando il nome confuso, @TheBlast, si parla molto del nome confuso. –

+1

SetSubComponent() è l'approccio corretto. RegisterNoIcon() può avere un effetto collaterale utile (non sono sicuro che lo faccia, non l'ho testato) ma in realtà, tecnicamente, non fa ciò che è richiesto (eccetto per caso, nel qual caso potrebbe legittimamente smettere di farlo ad un certo punto). – Deltics

4

Quando si creano i controlli interni, dite loro che il loro proprietario è la forma (il proprietario del controllo esterno). Pertanto, il modulo li disegna, proprio come se disegna tutti gli altri componenti che possiede. Probabilmente vuoi che il controllo esterno possieda quelli interiori.

5

Se TInnerControl deve essere utilizzato solo all'interno di un TOuterControl, è necessario chiamare SetSubComponent (True) durante/dopo la creazione di TInnerControl.

+1

Non sono sicuro del motivo per cui non è stata accettata come risposta corretta. Questa è la risposta corretta. Posso solo pensare che RegisterNoIcon possa avere un utile effetto collaterale (non ho provato per vedere se è così). – Deltics

Problemi correlati