2010-11-22 36 views
6

我創建了一個自定義控件TOuterControl,它是多個TInnerControls的父項。防止Delphi IDE在設計時創建組件圖標

除了IDE正在爲每個孩子TInnerControl(在屏幕截圖中的InnerControl1和InnerControl2)創建圖標之外,一切正常。如何防止IDE生成圖標?

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

看起來你正在重新創造'TCollection'。使內部「控件」從「TCollectionItem」下降,爲外部控件定義一個小的「TOwnedCollection」後裔,並解決所有設計時管理任務。 – 2010-11-22 06:06:30

+0

使用TCollectionItem和TOwnedCollection在我的情況下沒有意義,我發佈的代碼是一個簡化示例。 – Frank 2010-11-22 06:39:35

+0

爲什麼沒有道理?你想完成什麼TCollection/TCollectionItem不能完全處理? – 2010-11-22 21:40:00

回答

7

可以防止它們在表單上appeaing:

RegisterNoIcon([TInnerControl]); 

上RegisterNoIcon更多信息,可以在http://docwiki.embarcadero.com/VCL/e/index.php/Classes.RegisterNoIcon

發現這是一個以「控制」結尾有點混亂,有教學班,一個名字這不是正常的視覺控制。

+0

+1因爲我們沒有「註冊圖標」,但沒有提供組件調色板圖標,所以我們沒有注意到「RegisterNoIcon」短語也令人困惑。 RegisterWithoutIcon或甚至RegisterComponentsWithoutIcon會更自我記錄。 – TheBlastOne 2010-11-22 11:46:08

+0

作爲一個投票贊成這個答案的人,不是提及這個令人困惑的名字@TheBlast,你確實談了很多關於這個令人困惑的名字。 – 2010-11-23 20:51:37

+1

SetSubComponent()是正確的方法。 RegisterNoIcon()可能有一個有用的副作用(我不確定它是否存在,我沒有測試過),但在技術上並沒有做到所要求的事情(除非意外,在這種情況下它可能會合法地停止這樣做在某一點)。 – Deltics 2010-11-24 00:57:40

4

當您創建內部控制,你告訴他們,他們的主人是形式(外部控制的所有者)。因此,表單繪製它們,就像繪製它擁有的所有其他組件一樣。你可能希望外部控制擁有內部控制。

5

如果TInnerControl僅用於TOuterControl內部,則應在TInnerControl創建期間/之後調用SetSubComponent(True)。

+1

我不確定爲什麼這不被接受爲正確的答案。這是正確的答案。我只能認爲RegisterNoIcon可能有一個有用的副作用(我沒有測試過,看看是否是這種情況)。 – Deltics 2010-11-24 00:57:03