Bonjour,
Ma réponse arrive peu-être un peu tard, mais c'est en cherchant un exemple de code pour créer un composant possédant une collection éditable dans l'EDI que je suis tombé sur votre message...
Pour ma part, je suis habitué à créer des composants qui possèdent des références sur d'autres composants (mais pas des collections), et je pense utile de vous apporter quelques précisions à ce sujet.
Donc dans le cas simple d'un TcomposantA qui possède une référence sur un TComposantB, on déclare simplement
1 2 3 4 5 6
| TComposantA = class(TComponent)
private
FcompoB : TComposantB;
public
CompoB : TComposantB read FCompoB write FcompoB;
end; |
Inutile d'écrire un attribut supplémentaire pour stocker son Owner.
Enuite, lorsqu'on observe la fiche en mode texte, si le compoB a le même owner que le composantA, alors la propriété publiée s'écrit simplement
tandis que si leur owner est différent (composant B sur une autre fiche par exemple), on lit alors
CompoB = NomDuOwnerDeB.NomDuComposantB
Je pense donc que c'est ce principe qui vous a surpris, mais c'est le fonctionnement normal de Delphi, et c'est ce qui lui permet de recharger correctement le bon pointeur dans l'attribut FCompoB à la relecture du dfm.
Donc si vous utilisez simplement le code suivant je pense que ça devrait marcher :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| unit Collection_Unit;
interface
uses Classes;
type
TMonCollectionItem = class( TCollectionItem )
protected
FNom: String;
FCompo: TComponent;
public
procedure Assign(Source: TPersistent); override;
published
property Nom: String read FNom write FNom;
property Compo: TComponent read FCompo write FCompo;
end;
TMonComposant = class( TComponent )
private
FMaCollection: TOwnedCollection;
procedure SetMaCollection(const Value: TOwnedCollection);
public
Constructor Create( AOwner: TComponent ); override;
Destructor Destroy; override;
published
property MaCollection: TOwnedCollection read FMaCollection write SetMaCollection;
end;
procedure Register;
implementation
uses Forms;
procedure Register;
begin
RegisterComponents( 'Samples', [TMonComposant] );
end;
{ TMonComposant }
constructor TMonComposant.Create(AOwner: TComponent);
begin
inherited;
FMaCollection := TOwnedCollection.Create( Self, TMonCollectionItem );
end;
destructor TMonComposant.Destroy;
begin
FMaCollection.Free;
inherited;
end;
procedure TMonComposant.SetMaCollection(const Value: TOwnedCollection);
begin
FMaCollection.Assign( Value );
end;
{ TMonCollectionItem }
procedure TMonCollectionItem.Assign(Source: TPersistent);
begin
if ( Source is TMonCollectionItem ) then
begin
FNom := TMonCollectionItem( Source ).Nom;
FCompo := TMonCollectionItem( Source ).Compo ;
end
else
inherited;
end;
end. |
Attention toutefois, il y a peut-être une subtilité avec TMonComposant.SetMaCollection, comme avec les TStrings, mais je ne l'ai plus en tête. Alors comme ceci correspond exactement à ce que j'ai besoin de faire, je teste dès que possible et je vous tiens au courant !
Cordialement.
Partager