Accéder aux objets dynamique [Résolu]

gebu34 119 Messages postés samedi 9 décembre 2006Date d'inscription 17 novembre 2009 Dernière intervention - 11 mai 2007 à 11:16 - Dernière réponse : cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention
- 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
Afficher la suite 

Votre réponse

10 réponses

Meilleure réponse
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 12 mai 2007 à 19:07
3
Merci
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)

Merci f0xi 3

codes-sources a aidé 81 internautes ce mois-ci

Commenter la réponse de f0xi
Meilleure réponse
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 13 mai 2007 à 01:57
3
Merci
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)

Merci f0xi 3

codes-sources a aidé 81 internautes ce mois-ci

Commenter la réponse de f0xi
cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention - 11 mai 2007 à 11:47
0
Merci
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.
Commenter la réponse de cs_Loda
gebu34 119 Messages postés samedi 9 décembre 2006Date d'inscription 17 novembre 2009 Dernière intervention - 11 mai 2007 à 16:03
0
Merci
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+
Commenter la réponse de gebu34
gebu34 119 Messages postés samedi 9 décembre 2006Date d'inscription 17 novembre 2009 Dernière intervention - 11 mai 2007 à 19:08
0
Merci
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+.
Commenter la réponse de gebu34
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 11 mai 2007 à 20:36
0
Merci
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)
Commenter la réponse de f0xi
gebu34 119 Messages postés samedi 9 décembre 2006Date d'inscription 17 novembre 2009 Dernière intervention - 12 mai 2007 à 08:39
0
Merci
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
Commenter la réponse de gebu34
gebu34 119 Messages postés samedi 9 décembre 2006Date d'inscription 17 novembre 2009 Dernière intervention - 13 mai 2007 à 00:03
0
Merci
Ok, c'est clair, en plus j'aime bien ce code.
Il ne me reste qu'a me mettre au clavier....
Merci
A+
Commenter la réponse de gebu34
gebu34 119 Messages postés samedi 9 décembre 2006Date d'inscription 17 novembre 2009 Dernière intervention - 13 mai 2007 à 21:44
0
Merci
Grand merci
A+
Commenter la réponse de gebu34
cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention - 14 mai 2007 à 09:10
0
Merci
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.
Commenter la réponse de cs_Loda

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.