Evennement et Array, Comment avoir évenement quand une valeur d'une array change

Résolu
ptitjib Messages postés 7 Date d'inscription samedi 9 mai 2009 Statut Membre Dernière intervention 12 mai 2009 - 18 oct. 2008 à 19:56
ptitjib Messages postés 7 Date d'inscription samedi 9 mai 2009 Statut Membre Dernière intervention 12 mai 2009 - 24 oct. 2008 à 02:42
Comment avoir un évenement quand une valeur d'une array change ?
Voici un exemple concret qui ne fonctionne pas, j'aimerais comprendre pourquoi et savoir comment m'y prendre.

Rien de plus parlant qu'un morceau de code.

Type TDoubleArray = Array of Double;
Type TCoefsChangeEvent = Procedure(Sender : TObject; aCoefs : TDoubleArray) of Object;
Type TMyObject = class (TObject);
               Private
                  FCoefs : TDoubleArray;
                  FonCoefsChange : TCoefsChangeEvent;
                  Procedure SetCoefs(aCoefs : array of Double)
               Public
                   Procedure test;
                   Constructor ....
               Publisched
                    Property Coefs : TDoubleArray read FCoefs write SetCoefs;
                    Property OnCoefsChange : TCoefsChangeEvent read FonCoefsChange write FonCoefsChange

end;

implementation

Procedure TMyObject.SetCoefs(aCoefs : Array of Double)
 var i : integer;
begin
  if FCoefs<>aCoefs then
    begin
      For i: =0 to Length(FCoefs) do
        FCoefs[i]:= aCoef[i];
      If Assign(FOnCoefChange) then
        FOnCoefChange(FCoefs);
    end;
end;

Procedure TMyObject.test;
var
 listcoefs : array of double;
 i : integer;
begin
randomize;
 for i: =0 to 10 do
   begin
      SetLength(listcoefs, length(listcoefs)+1);
      Listcoefs[i] := 1 - random(1000)/1000;
      Coefs[i] := Listcoefs[i];   <---------------------  Ici le fait de charger les coefs ne déclenche pas l'évenement.
   end;
end;

3 réponses

ptitjib Messages postés 7 Date d'inscription samedi 9 mai 2009 Statut Membre Dernière intervention 12 mai 2009
24 oct. 2008 à 02:42
Bonsoir,
Merci à Foxi, je ne connaissais pas la forme "Values[index : integer] : integer".
Ton astuce du begin/endupdate set ou pas le déclanchement des évenements, on set donc Values[i] entre les deux. Le pointeur permet une modification directe de la valeur de l'index [i] de fMyArray renvoyé par l'évenemnt de cette instance de TMyObject et permet donc de ne pas déclancher d'évenement en la modifiant.
Bonne exemple,
A bientôt.
3
ptitjib Messages postés 7 Date d'inscription samedi 9 mai 2009 Statut Membre Dernière intervention 12 mai 2009
19 oct. 2008 à 00:59
Bonjour,

Toujours pas de réponses depuis quelques heures, j'ai cependant continué à chercher pour enfin trouver la solution, que je vais empressément communiquer pour ceux qui se poseraient la question.

J'ai donc transformé mon TDoubleArray en une Array d'un autre objet instancié : un Array of TCoef. Ce TCoef comprend la méthode SetCoef(aCoef:Double) qui me déclanche l'évenement.

Type TDoubleArray = Array of Double;
Type TCoefChangeEvent = Procedure(Sender : TObject; aCoefs : TDoubleArray) of Object;

Type TCoef = Class(TObject)
   Private
    FCoef : Double;
    FCoefChange : TCoefChangeEvent ;
   Public
    Constructor Create();
   Publisched
    Property Coef : Double read FCoef write SetCoef;
    Property OnCoefChange : TCoefChangeEvent read FCoefChange write FCoefChange;
End;
Type TArrayCoefs = Array of TCoef;

Type TMyObject = class(TObject);
               Private
                  FCoefs : TArrayCoefs;
                  Procedure SetCoefs(aCoefs : array of Double)
               Public
                   Procedure test;
                   Constructor ....
               Publisched
                    Property Coefs : TArrayCoefs read FCoefs write FCoefs;

end;

implementation

Procedure TCoef.SetCoefs(aCoef : Double)
 var i : integer;
begin
  if FCoefs<>aCoefs then
    begin
      For i:= 0 to Length(FCoefs) do
        FCoefs[i]: =aCoef[i];
      If Assign(FCoefChange) then
        FCoefChange(FCoef);
    end;
end;

Procedure TMyObject.test;
var
 listcoefs : array of double;
 i : integer;
begin
randomize;
 for i:= 0 to 10 do
   begin
      SetLength(listcoefs, length(listcoefs)+1);
      Listcoefs[i] : = 1 - random(1000)/1000;
      Coefs[i] := TCoef.Create();  
      Coefs[i].OnCoefsChange : = Procedure <---------------------  on assigne la procedure de l'evenement ici
      Coefs[i].Coef := 1.3;  < Super ça marche, l'évenement est déclanché !
   end;
end;

J'espère que cela vous sera util au moins.
A bientôt.
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
20 oct. 2008 à 00:49
type
  TMyArray = array[0..n] of integer;

  TValueChangeEvent = procedure(Sender: TObject; const index: integer; const value: pointer) of object;

  TMyObject = class
  private
    fUpdate  : integer;
    fMyArray : TMyArray;
    fOnValueChange: TValueChangeEvent;
    procedure SetValue(index: integer; value: integer);
    function GetValue(index: integer): integer;
  protected
    property OnValueChange: TValueChangeEvent read fOnValueChange write fOnValueChange;
  public
    constructor Create;
    property Values[index: integer]: integer read GetValue write SetValue;
    procedure BeginUpdate;
    procedure EndUpdate;
  end;

constructor TMyObject.Create;
begin
  fUpdate := 0;
end;

procedure TMyObject.BeginUpdate;
begin
  inc(fUpdate);
end;

procedure TMyObject.EndUpdate;
begin
  dec(fUpdate);
  if fUpdate = 0 then
    if Assigned(fOnValueChange) then
      fOnValueChange(self, -1, nil);
end;

procedure TMyObject.SetValue(index: integer; value: integer);
begin
  if fMyArray[index] <> Value then
  begin
    fMyArray[index] := Value;

    if fUpdate = 0 then
      if assigned(fOnValueChange) then
        fOnValueChange(self, index, @fMyArray[index]);
  end;
end;

function TMyObject.GetValue(index: integer): integer;
begin
  result := fMyArray[index];
end;








<hr size="2" width="100%" />
0
Rejoignez-nous