Преглед изворни кода

* Fix OnChange being fired twice when adding an object. Fixes issue 40261

Michaël Van Canneyt пре 1 година
родитељ
комит
ab4db7f475
2 измењених фајлова са 89 додато и 4 уклоњено
  1. 14 4
      rtl/objpas/classes/stringl.inc
  2. 75 0
      tests/test/units/classes/tstrlonchange.pp

+ 14 - 4
rtl/objpas/classes/stringl.inc

@@ -1065,8 +1065,13 @@ end;
 Function TStrings.AddObject(const S: string; AObject: TObject): Integer;
 
 begin
-  Result:=Add(S);
-  Objects[result]:=AObject;
+  BeginUpdate;
+  try
+    Result:=Add(S);
+    Objects[result]:=AObject;
+  finally
+    EndUpdate;
+  end;
 end;
 
 function TStrings.AddObject(const Fmt: string; Args : Array of const; AObject: TObject): Integer;
@@ -1324,8 +1329,13 @@ Procedure TStrings.InsertObject(Index: Integer; const S: string;
   AObject: TObject);
 
 begin
-  Insert (Index,S);
-  Objects[Index]:=AObject;
+  BeginUpdate;
+  try
+    Insert (Index,S);
+    Objects[Index]:=AObject;
+  finally
+    EndUpdate;
+  end;
 end;
 
 function TStrings.LastIndexOf(const S: string): Integer;

+ 75 - 0
tests/test/units/classes/tstrlonchange.pp

@@ -0,0 +1,75 @@
+program sl;
+//issue #40261
+{$mode objfpc}
+{$WARN 5024 off : Parameter "$1" not used}
+uses
+  SysUtils, Classes;
+
+type
+  TTest = class
+  private
+    FList: TStringList;
+    FCount: Integer;
+    procedure Change(Sender: TObject);
+  public
+    constructor Create;
+    destructor Destroy; override;
+    procedure DoTest;
+  end;
+
+procedure assertOK(B : Boolean; Msg : String);
+
+begin
+  if not B then
+    begin
+    Writeln(Msg);
+    Halt(1);
+    end;
+end;
+
+procedure TTest.Change(Sender: TObject);
+begin
+  Inc(FCount);
+end;
+
+constructor TTest.Create;
+begin
+  FCount := 0;
+  FList := TStringList.Create;
+  FList.OwnsObjects := True;
+  FList.OnChange := @Change;
+end;
+
+destructor TTest.Destroy;
+begin
+  FList.Free;
+  inherited Destroy;
+end;
+
+procedure TTest.DoTest;
+begin
+  FCount := 0;
+  FList.AddObject('Added',TObject.Create);
+  AssertOK(FCount=1,format('AddObject causes %d OnChanges, expected 1',[FCount]));
+
+  FCount := 0;
+  FList.InsertObject(0, 'Inserted',TObject.Create);
+  AssertOK(FCount=1,format('InsertObject causes %d OnChanges, expected 1',[FCount]));
+
+  FCount := 0;
+  FList.AddPair('Name','Value',TObject.Create);
+  AssertOK(FCount=1,format('InsertObject causes %d OnChanges, expected 1',[FCount]));
+end;
+
+var
+  T: TTest;
+
+begin
+  T := TTest.Create;
+  try
+    T.DoTest;
+  finally
+    T.Free;
+  end;
+end.
+