2012-02-24 10 views
7

Voglio che la mia componente che sarà non visivo per avere le sue proprietà pubblicati sotto una categoria non al livello superiore del Inspector.Come posso raggruppare le proprietà del mio componente in Object Inspector?

Prendiamo l'esempio qui sotto:

enter image description here

type 
    TMyComponent = class(TComponent) 
    protected 
    function GetSomeValue: string; 
    function GetSomeValueExt: string; 
    published 
    property SomeValue: string read GetSomeValue; 
    property SomeValueExt: string read GetSomeValueExt; 
    end; 

procedure Register; 

implementation 

procedure Register; 
begin 
    RegisterComponents('My Component', [TMyComponent]); 
end; 

function TMyComponent.GetSomeValue: string; 
begin 
    Result := 'test'; 
end; 

function TMyComponent.GetSomeValueExt: string; 
begin 
    Result := 'extended..'; 
end; 

Come faccio ad avere il mio componente per registrare in Inspector con SomeValue e SomeValueExt sotto una categoria denominata qualcosa come MyProperties?

Illustrazione:

enter image description here

mio componente potrebbe potenzialmente avere un sacco di proprietà pubblicati e avrei preferito che è andato sotto c'è proprio livello sottocategoria della Inspector per tenerlo lontano dalle proprietà comuni come Nome e tag.

Grazie :)

+0

Stai parlando il termine Categoria che viene utilizzato da Inspector? Questa è la funzione in cui fai clic con il tasto destro su OI e seleziona "Visualizza per categoria". –

+0

Dite come esempio che fate clic su TForm o su un altro componente, alcune proprietà sono sotto categorie come Ancore, BorderIcons e Font ecc.Voglio che alcune delle mie proprietà abbiano i propri genitori se ciò ha senso. –

+0

'Ancoraggi' e' BorderIcons' sono set. Tu non vuoi quello. La proprietà 'Font' è una classe. Quindi potresti avvolgere le tue sub-proprietà in una classe e ottenere il comportamento che desideri gratuitamente. –

risposta

17

creare una classe che ha quelle caratteristiche, e poi dare il componente una singola proprietà di quel tipo di classe. La classe di proprietà deve essere un discendente TPersistent:

type 
    TComponentProperties = class(TPersistent) 
    private 
    function GetSomeValue: string; 
    function GetSomeValueExt: string; 
    published 
    property SomeValue: string read GetSomeValue; 
    property SomeValueExt: string read GetSomeValueExt; 
    end; 

    TMyComponent = class(TComponent) 
    private 
    FProperties: TComponentProperties; 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    published 
    property Properties: TComponentProperties read FProperties; 
    end; 

Il componente possiede il suo oggetto di proprietà, quindi ha bisogno di essere creato e distrutto:

constructor TMyComponent.Create; 
begin 
    inherited; 
    FProperties := TComponentProperties.Create; 
end; 

destructor TMyComponent.Destroy; 
begin 
    FProperties.Free; 
    inherited; 
end; 

Con questo codice, le proprietà del componente dovrebbero ora essere incluso sotto la voce "Proprietà". Non è una categoria, però. Le categorie sono qualcos'altro interamente. Le categorie non riorganizzano il componente; cambiano semplicemente il modo in cui le proprietà sono visualizzate nell'Object Inspector. Si noti che con il mio codice, TMyComponent non ha più alcuna proprietà SomeValue. Invece, ha solo una proprietà, Properties, e che oggetto ha altre proprietà. Pensa se è davvero così che vuoi che i consumatori del tuo componente debbano accedervi.


Se la proprietà Properties non è di sola lettura, quindi ha bisogno di avere un setter di proprietà; non puoi farlo scrivere direttamente a FProperties. Scrivere in questo modo:

procedure TMyComponent.SetProperties(const Value: TProperties); 
begin 
    FProperties.Assign(Value); 
end; 

che richiede anche che l'override del metodo Assign di fare la cosa giusta:

procedure TComponentProperties.Assign(Other: TPersistent); 
begin 
    if Other is TComponentProperties then begin 
    SomeValue := TComponentProperties(Other).SomeValue; 
    SomeValueEx := TComponentProperties(Other).SomeValueEx; 
    end else 
    inherited; 
end; 

Stiamo anche assumendo che le proprietà dell'oggetto proprietà non sono di sola lettura , o. Quando le proprietà dell'oggetto della proprietà cambiano, l'oggetto proprietario probabilmente vorrà saperlo, quindi dovrebbe avere un evento a cui il componente assegna un valore. Quando le proprietà cambiano, attiveranno l'evento.

+0

Grazie per l'informazione, ho avuto la sensazione che le categorie potrebbero non spiegarlo al meglio. Uso Delphi per uso personale quindi non sarà in alcun modo nessun altro a usare il mio componente, ma vale sempre la pena di considerare se in futuro qualcuno dovesse usarlo. Grazie :) –

+1

Quando ho detto "consumatori del tuo componente", * incluso * tu. Vuoi * tu * voler digitare 'Properties.SomeValue' tutto il tempo? –

+0

Non preoccuparti, stavo per darmi la possibilità di controllare tutto e assicurarmi di capirlo prima! :) –

Problemi correlati