Accéder aux objets dynamique

Résolu
gebu34 Messages postés 118 Date d'inscription samedi 9 décembre 2006 Statut Membre Dernière intervention 17 novembre 2009 - 11 mai 2007 à 11:16
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 - 14 mai 2007 à 09:10
Salut à tous,
Je crée dynamiquement un ComboBox sur une Form.
J'ai élaguer volontairement le code pour ne pas surchager....

var
  CmBx: TComboBox;
  Objects: array of TControl;
..............
CmBx := TComboBox.Create(Self);
with CmBx do
  begin
    Parent := Self;
    Name := 'CB1';
    OnClick := CmBxClick;
    SetBounds(100, 100, 150, 17);
  end;
SetLength(Objects, Length(Objects) + 1);
Objects[High(Objects)] := CmBx;

On peut charger la ComboBox par : CmBx.Items.Add(NomVariable);
On peut lire sur Click avec : variable := CmBx.Text;

Ca c'est bien quand on a 1 ComboBox... Mais avec plusieurs CB1, CB2 ?????

A+
Merci

10 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
12 mai 2007 à 19:07
procedure TForm1.FormCreate(Sender: TObject);
var N,II,OT,OH : integer;
begin
  CreateChild('',TEdit,Self,10,10,II);
  with DynamicCtrls.Items[II] as TEdit do
  begin
    Text := 'Hahahahaha';
    OT := Top;
    OH := Height;
  end;

  CreateChild('',TComboBox,Self,10,OT+OH+8,II);
  with DynamicCtrls.Items[II] as TComboBox do
  begin
    for N := 1 to 10 do
        Items.Add(IntToStr(N));
  end;
end;



function TForm1.CreateChild(const AName : string; AClass : TControlClass;
                            AParent : TWinControl; const ALeft, ATop : integer;
                            var VIndex : integer) : TControl;

begin
  result := AClass.Create(nil);
  VIndex := fDynCtrlList.Add(result);





DynamicCtrls fonctione comme la propriété Items ou Lines d'une ListBox ou Memo, juste que la ce n'est pas des chaines mais des objets.

pour assigner les evenements, tu créer des gestionnaire dans l'objet ou la fiche que tu desire, puis, tu assigne les gestionnaires comme suis :

CreateChild('DEdit1',TEdit,Self,10,10,II);
with DynamicCtrls.Items[II] as TEdit do
begin
  Text       := '';
  OnClick    := DoDEdit1Click;
  OnChange   := DoDEdit1Change;
  OnKeyPress := DoDEdit1KeyPress;
end;

<hr size="2" width="100%" />Croc (click me)
3
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
13 mai 2007 à 01:57
ah et pour enlever un objet de la fiche tu fait :

DynamicCtrls.Delete(index de l'objet);

Delete s'occupera de la suppression et liberation de l'objet.

<hr size="2" width="100%" />Croc (click me)
3
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
11 mai 2007 à 11:47
salut,

var
MesCB : array[1..NBCB] of TcomboBox;

for i := 1 to NBCB do begin
CmBx := TComboBox.Create(Self);
with CmBx do
  begin
    Parent := Self;
//    Name := 'CB1'; // inutile ou CB + inttostr(i)
    OnClick := CmBxClick;
    SetBounds(100, 100+i*..., 150, 17);
   tag := i; // si ça t'aide....
  end;
  MesCB[i]:=cmbx;
end;
n'oublie pas que les event pass en param le "sender" ! Aussi, rappel toi le champs tag!

A+

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
0
gebu34 Messages postés 118 Date d'inscription samedi 9 décembre 2006 Statut Membre Dernière intervention 17 novembre 2009
11 mai 2007 à 16:03
Re,
J'ai pris un tableau TControl car mets dedans aussi du TCheckBox et du TEdit.
Ca ne change pas grand chose. J'avais déjà vu la possibilité d'utiliser Tag, qui peut-être fort util dans ce cas. Mais pour accéder aux propriétés du compo, il existe peut-être un manière plus simple que :
for i:=0 to Length(Objects)-1 do
  begin
    if Objects[i].Tag = 2
    ou
    if Objects[i].Name = 'CB1'
  end;
pour récupérer l'indice de l'objet.....
A+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
gebu34 Messages postés 118 Date d'inscription samedi 9 décembre 2006 Statut Membre Dernière intervention 17 novembre 2009
11 mai 2007 à 19:08
Salut Loda,
J'étais en train de relire ton message, et je pense que tu as la solution. Je m'acharne à avoir un tableau TControl pour pouvoir mettre toute sorte de composants, alors que déclarer un tableau par composant TComboBox, TCheckBox, TEdit est plus lourd en code, mais plus simple à gérer (remplir des listes, extraire des données...)
Qu'en penses-tu ?
A+.
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
11 mai 2007 à 20:36
ptite technique de derriere les fagots :

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs;

type
  TControlClass = class of TControl;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    fDynCtrlList  : TObjectList;
  protected
  public
   constructor Create(AOwner : TComponent); override;
   destructor Destroy; override;
   function CreateChild(const AName : string; AClass : TControlClass;
                        AParent : TWinControl; const ALeft, ATop : integer;
                        var VIndex : integer) : TControl;
   property DynamicCtrls : TObjectList read fDynCtrlList write fDynCtrlList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fDynCtrlList := TObjectList.Create(true);
end;

function TForm1.CreateChild(const AName : string; AClass : TControlClass;
                            AParent : TWinControl; const ALeft, ATop : integer;
                            var VIndex : integer) : TControl;
begin
  result := AClass.Create(nil);
  VIndex := fDynCtrlList.Add(result);
  with Result do
  begin
    if Length(AName) >= 2 then
       Name   := AName
    else
       Name   := 'DynamicCtrl'+IntToStr(fDynCtrlList.Count);

    if AParent <> nil then
       Parent := AParent;

    SetBounds(ALeft,ATop,Width,Height);
  end;
end;

destructor TForm1.Destroy;
begin
  fDynCtrlList.Clear;
  fDynCtrlList.Free;
  inherited Destroy;
end;

procedure TForm1.FormCreate(Sender: TObject);
var N,II,OT,OH : integer;
begin
  CreateChild('',TEdit,Self,10,10,II);
  with DynamicCtrls.Items[II]as TEdit do
  begin
    Text := 'Hahahahaha';
    OT := Top;
    OH := Height;
  end;

  CreateChild('',TComboBox,Self,10,OT+OH+8,II);
  with DynamicCtrls.Items[II] as TComboBox do
  begin
    for N := 1 to 10 do
        Items.Add(IntToStr(N));
  end;
end;

<hr size="2" width="100%" />Croc (click me)
0
gebu34 Messages postés 118 Date d'inscription samedi 9 décembre 2006 Statut Membre Dernière intervention 17 novembre 2009
12 mai 2007 à 08:39
Salut,
En ce moment je me connecte en pointillés j'ai des problèmes sur la ligne.
La, FOxi nous présente THE code....
J'aime bien, c'est clair et nul doute efficace...
Petite question, ta variable II (Vindex) est initialisée comment ?Dans mon cas, je veux faire apparaître les compos "à la volée" (un click sur une cellule d'un STringGrid visible  une autre cellule libéré). Je pense qu'il suffit de déclaré CreateChild non pas dans FormCreate mais dans OnSelectCell.
Par contre pour récupérer les données de ces compos comment utiliser DynamicCtrls ?
(Par exemple le OnClick d'un ComboBox remplis la cellule 1,1 d'un TStringGrid)
A+
et merci de vos efforts
0
gebu34 Messages postés 118 Date d'inscription samedi 9 décembre 2006 Statut Membre Dernière intervention 17 novembre 2009
13 mai 2007 à 00:03
Ok, c'est clair, en plus j'aime bien ce code.
Il ne me reste qu'a me mettre au clavier....
Merci
A+
0
gebu34 Messages postés 118 Date d'inscription samedi 9 décembre 2006 Statut Membre Dernière intervention 17 novembre 2009
13 mai 2007 à 21:44
Grand merci
A+
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
14 mai 2007 à 09:10
salut,

"Mais pour accéder aux propriétés du compo"

1. une recherche (ie: for) dans le tableau selon un critère (tag, name, type, ...)
2. tu garde le pointeur quelque part. (ex: dans le champs object d'une stringlist) -> acces (presque) sans recherche. Attention au AV.
3.tu ne garde pas le compo dans un tableau mais dans une var réservée pour cette usage. (var EdtDynClientName, ....)

bon code,

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
0
Rejoignez-nous