2010-11-22 10 views
6

He creado un control personalizado TOuterControl que es el padre de múltiples TInnerControls.Evitar que Delphi IDE cree íconos de componentes en el momento del diseño

Todo funciona bien excepto que el IDE está creando íconos para cada uno de los controles TInnerControl (InnerControl1 e InnerControl2 en la captura de pantalla). ¿Cómo evito que el IDE genere los iconos?

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

Parece que estás reinventando 'TCollection'. Haga que los "controles" internos descienden de 'TCollectionItem', defina un pequeño descendiente' TOwnedCollection' para que lo tenga el control externo, y todas sus tareas de administración en tiempo de diseño serán resueltas. –

+0

El uso de TCollectionItem y TOwnedCollection no tiene sentido en mi situación, el código que publiqué es un ejemplo de reducción. – Frank

+0

¿Por qué no tiene sentido? ¿Qué intenta lograr que TCollection/TCollectionItem no pueda manejar exactamente? –

Respuesta

7

Puede evitar que appeaing en el formulario con:

RegisterNoIcon([TInnerControl]); 

Más información sobre RegisterNoIcon se puede encontrar en http://docwiki.embarcadero.com/VCL/e/index.php/Classes.RegisterNoIcon

Es un poco confusas que tienen clases con un nombre que terminan con "Control" que no son controles visuales normales sin embargo.

+0

+1 por no mencionar la frase "RegisterNoIcon" también es confusa, porque no "registramos ningún icono", pero sí nos registramos sin un ícono de paleta de componentes. RegisterWithoutIcon o incluso RegisterComponentsWithoutIcon habría sido más autodocumentado. – TheBlastOne

+0

Como alguien que votó esta respuesta por * no * mencionar el nombre confuso, @TheBlast, seguro hablas mucho sobre el nombre confuso. –

+1

SetSubComponent() es el enfoque correcto. RegisterNoIcon() puede tener un efecto secundario útil (no estoy seguro de que lo haga, no lo he probado) pero en realidad no hace, técnicamente, lo que se requiere (excepto por accidente, en cuyo caso puede dejar de hacerlo legítimamente) en algún momento). – Deltics

4

Al crear los controles internos, se les dice que su propietario es la forma (el propietario del control externo). Por lo tanto, la forma los dibuja, al igual que dibuja todos los otros componentes que posee. Probablemente desee que el control externo sea el propietario de los internos.

5

Si TInnerControl está destinado a ser utilizado solo dentro de un TOuterControl, entonces debe llamar a SetSubComponent (True) durante/después de la creación de TInnerControl.

+1

No estoy seguro de por qué esto no fue aceptado como la respuesta correcta. Esta es la respuesta correcta. Solo puedo pensar que RegisterNoIcon puede tener un efecto secundario útil (no he probado para ver si ese es el caso). – Deltics

Cuestiones relacionadas