Bonjour,
Dans un composant (visuel), j'ai une propriété property DataSet: TDataSet.
Lorsque j'associe par l'Inspecteur d'Objet par exemple un Zquery1 déposé sur la Form à la dite propriété, pas de problème.
Si je change le nom du zQuery1 par zQuery2 dans l'Inpecteur d'Objet du Zquery, le nouveau nom apparaît automatiquement dans la propriété DataSet de mon composant.
Mais si je sélectionne le zQuery1 de la Form et que je le supprime de cette dernière et si je veux ensuite sauvegarder ma Form à partir de l'IDE, j'obtiens un magnifique plantage... et la fermeture de Lazarus... et ceci même si le code est minimaliste dans le composant.
En clair, la modification du nom du composant zQuery est corrigée automatiquement dans la propriété DataSet de mon composant alors que visiblement la suppression du zQuery de la Form n'est pas gérée automatiquement par mon composant.
Pour l'instant, j'ai réglé le problème ainsi : je détecte la Form sur laquelle est posée mon composant, ce qui me permet de vérifier si la valeur 'zQuery1' contenue dans la propriété DataSet (de mon composant) correspond ou non à un zQuery existant dans la Form.
Cela m'oblige à utiliser une fonction spécifique pour le read au lieu d'un simple read FDataSet.
Je copie la partie utile du code.
Cela a l'air de "fonctionner" au sens où le problème de suppression du DataSet dans la Form ne pose plus de problème. Mais cela me semble très lourd et inadapté : ce bricolage maison n'est certainement pas la bonne méthode. D'autant que si le DataSet est défini par programmation dans une autre Form (MyComponent1.DataSet := Form2.zQuery2) ou un DataModule, cela coince.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 type TMyComponent = class(TCustomStringGrid) private { Private declarations } procedure SetDataSet(ADataSet: TDataSet); function GetDataset: TDataSet; procedure StringGridCreate(Sender: TObject); function DataSetExist(xDataSet:TDataSet) : boolean; protected { Protected declarations } FormAOwner:TForm; {[En cas de suppression du DataSet dans l'IDE]} public { Public declarations } FDataSet: TDataSet; constructor Create(AOwner: TComponent); override; destructor Destroy; override; published { Published declarations } property DataSet: TDataSet read GetDataSet write SetDataSet; end; [...] function TMyComponent.DataSetExist(xDataSet:TDataSet) : boolean; {Objet : Vérifie si le DataSet existe notamment lors de sa suppression directe dans l'IDE [sinon plantage de l'IDE]--> cf GetDataSet} var iLoc : Integer; begin Result := False; if xDataSet = nil then exit; if FormAOwner.ComponentCount <1 then exit; for iLoc := 0 to FormAOwner.ComponentCount-1 do if FormAOwner.Components[iLoc].Name = xDataSet.Name then begin Result := True; break; end; end; constructor TMyComponent.Create(AOwner: TComponent); begin Inherited Create(AOwner); {Détermination de la Form contenant le composant : Nécessaire en cas de suppression du DataSet dans la Form cf function DataSetExist() : boolean;} FormAOwner := TForm(AOwner); end; function TMyComponent.GetDataset: TDataSet; begin if FDataSet = nil then Result := nil else begin if not DataSetExist(FDataSet) then Result := nil else Result := FDataset; end; end; procedure TMyComponent.SetDataSet(ADataSet: TDataSet); var i : integer; begin if ADataSet <> nil then begin if not DataSetExist(ADataSet) then ADataSet := nil; end; if FDataSet <> ADataSet then FDataSet := ADataSet; end;
Quelle est la bonne approche ?
Merci de votre aide.
Cordialement. Gilles
Partager