View Issue Details

IDProjectCategoryView StatusLast Update
0024753LazarusLCLpublic2013-09-26 18:27
ReporterRiskAssigned ToBart Broersma 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product VersionProduct Build 
Target Version1.2.0Fixed in Version1.1 (SVN) 
Summary0024753: TCheckGroup BeginUpdate causes Out of Bounds error
DescriptionWhen using TCheckGroup BeginUpdate an out of bounds error is thrown if you try to check the item. I have compared this on Delphi 5 and it works fine.
Steps To ReproduceSee attachment
TagsNo tags attached.
Fixed in Revisionr42772, r42774
LazTarget1.2
Widgetset
Attached Files
  • List index.zip (128,892 bytes)
  • cg.diff (1,795 bytes)
    Index: lcl/include/customcheckgroup.inc
    ===================================================================
    --- lcl/include/customcheckgroup.inc	(revision 42575)
    +++ lcl/include/customcheckgroup.inc	(working copy)
    @@ -14,15 +14,39 @@
     
     { TCustomCheckGroup }
     
    +type
    +
    +  { TCheckGroupStringList }
    +
    +  TCheckGroupStringList = class(TStringList)
    +  protected
    +    procedure Changed; override;
    +  public
    +    property UpdateCount;
    +  end;
    +
    +{ TCheckGroupStringList }
    +
    +procedure TCheckGroupStringList.Changed;
    +begin
    +  if (UpdateCount = 0)
    +    then inherited Changed
    +  else
    +  begin
    +    //we always need to update the associate checkboxes (Issue #0024753)
    +    if Assigned(OnChange) then OnChange(Self);
    +  end;
    +end;
    +
     constructor TCustomCheckGroup.Create(TheOwner: TComponent);
     begin
       inherited Create(TheOwner);
       FCreatingWnd := false;
       ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents, csSetCaption,
                                       csDoubleClicks];
    -  FItems      := TStringList.Create;
    +  FItems      := TCheckGroupStringList.Create;
       //TStringList(FItems).OnChanging := @ItemsChanged;
    -  TStringList(FItems).OnChange := @ItemsChanged;
    +  TCheckGroupStringList(FItems).OnChange := @ItemsChanged;
       FButtonList := TList.Create;
       FColumnLayout := clHorizontalThenVertical;
       FColumns  := 1;
    @@ -47,8 +71,12 @@
     procedure TCustomCheckGroup.ItemsChanged(Sender: TObject);
     begin
       UpdateItems;
    -  UpdateControlsPerLine;
    -  OwnerFormDesignerModified(Self);
    +  if (TCheckGroupStringList(FItems).UpdateCount = 0) then
    +  begin
    +    //only do visual updates when Items is not in BeginUpdate/EndUpdate
    +    UpdateControlsPerLine;
    +    OwnerFormDesignerModified(Self);
    +  end;
     end;
     
     procedure TCustomCheckGroup.ItemKeyDown(Sender: TObject; var Key: Word;
    
    cg.diff (1,795 bytes)
  • cg-alternative.diff (6,146 bytes)
    Index: lcl/include/customcheckgroup.inc
    ===================================================================
    --- lcl/include/customcheckgroup.inc	(revision 42575)
    +++ lcl/include/customcheckgroup.inc	(working copy)
    @@ -12,6 +12,83 @@
      *****************************************************************************
     }
     
    +Type
    +
    +  { TCheckGroupStringList }
    +
    +  TCheckGroupStringList = Class(TStringList)
    +  private
    +    FCheckGroup: TCustomCheckGroup;
    +    function CreateCheckBox: TCheckBox;
    +    procedure PrepareCheckBox(CB: TCheckBox);
    +  protected
    +    procedure InsertItem(Index: Integer; const S: string); override;
    +    procedure InsertItem(Index: Integer; const S: string; O: TObject); override;
    +  public
    +    constructor Create(TheOwner: TCustomCheckGroup);
    +    function AddObject(const S: string; AObject: TObject): Integer; override;
    +  end;
    +
    +{ TCheckGroupStringList }
    +
    +function TCheckGroupStringList.CreateCheckBox: TCheckBox;
    +var
    +  CheckBox: TCheckBox;
    +begin
    +  CheckBox := TCheckBox.Create(FCheckGroup);
    +  PrepareCheckBox(CheckBox);
    +  Result := CheckBox;
    +end;
    +
    +procedure TCheckGroupStringList.PrepareCheckBox(CB: TCheckBox);
    +begin
    +  with CB do begin
    +    Name:='CheckBox'+IntToStr(Self.Count);
    +    AutoSize := False;
    +    BorderSpacing.CellAlignHorizontal:=ccaLeftTop;
    +    BorderSpacing.CellAlignVertical:=ccaCenter;
    +    Parent := FCheckGroup;
    +    OnClick := @FCheckGroup.Clicked;
    +    OnKeyDown :=@FCheckGroup.ItemKeyDown;
    +    OnKeyUp := @FCheckGroup.ItemKeyUp;
    +    OnKeyPress := @FCheckGroup.ItemKeyPress;
    +    OnUTF8KeyPress := @FCheckGroup.ItemUTF8KeyPress;
    +    ParentFont := true;
    +    ControlStyle := ControlStyle + [csNoDesignSelectable];
    +  end;
    +
    +end;
    +
    +procedure TCheckGroupStringList.InsertItem(Index: Integer; const S: string);
    +begin
    +  inherited InsertItem(Index, S, CreateCheckBox);
    +end;
    +
    +procedure TCheckGroupStringList.InsertItem(Index: Integer; const S: string;
    +  O: TObject);
    +begin
    +  if not (O is TCheckBox) then Raise Exception.Create('Thou shalt not insert Objects into TCheckGroup.Items');
    +  inherited InsertItem(Index, S, O);
    +  TCheckBox(O).Parent := FCheckGroup;
    +end;
    +
    +constructor TCheckGroupStringList.Create(TheOwner: TCustomCheckGroup);
    +begin
    +  FCheckGroup := TheOwner;
    +end;
    +
    +function TCheckGroupStringList.AddObject(const S: string; AObject: TObject
    +  ): Integer;
    +begin
    +  //Called by Assign
    +  if (AObject = nil) then AObject := CreateCheckBox;
    +  if not (AObject is TCheckBox) then Raise Exception.Create('Thou shalt not insert Objects into TCheckGroup.Items.');
    +  PrepareCheckBox(TCheckBox(AObject));
    +  Result:=inherited AddObject(S, AObject);
    +  TCheckBox(AObject).Parent := FCheckGroup;
    +end;
    +
    +
     { TCustomCheckGroup }
     
     constructor TCustomCheckGroup.Create(TheOwner: TComponent);
    @@ -20,10 +97,11 @@
       FCreatingWnd := false;
       ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents, csSetCaption,
                                       csDoubleClicks];
    -  FItems      := TStringList.Create;
    -  //TStringList(FItems).OnChanging := @ItemsChanged;
    -  TStringList(FItems).OnChange := @ItemsChanged;
    -  FButtonList := TList.Create;
    +  FItems      := TCheckGroupStringList.Create(Self);
    +  TCheckGroupStringList(FItems).OwnsObjects := True;
    +  //TCheckGroupStringList(FItems).OnChanging := @ItemsChanged;
    +  TCheckGroupStringList(FItems).OnChange := @ItemsChanged;
    +//  FButtonList := TList.Create;
       FColumnLayout := clHorizontalThenVertical;
       FColumns  := 1;
       FAutoFill := true;
    @@ -40,13 +118,13 @@
     destructor TCustomCheckGroup.Destroy;
     begin
       FreeAndNil(FItems);
    -  FreeAndNil(FButtonList);
    +//  FreeAndNil(FButtonList);
       inherited Destroy;
     end;
     
     procedure TCustomCheckGroup.ItemsChanged(Sender: TObject);
     begin
    -  UpdateItems;
    +  //UpdateItems;
       UpdateControlsPerLine;
       OwnerFormDesignerModified(Self);
     end;
    @@ -105,7 +183,8 @@
     var
       Index: Integer;
     begin
    -  Index:=FButtonList.IndexOf(Sender);
    +  //Index:=FButtonList.IndexOf(Sender);
    +  Index := FItems.IndexOfObject(Sender);
       if Index<0 then exit;
       DoClick(Index);
     end;
    @@ -181,7 +260,8 @@
     begin
       if (Index < -1) or (Index >= FItems.Count) then
         RaiseIndexOutOfBounds(Index);
    -  Result:=TCheckBox(FButtonList[Index]).Enabled;
    +  //Result:=TCheckBox(FButtonList[Index]).Enabled;
    +  Result := TCheckBox(FItems.Objects[Index]).Enabled;
     end;
     
     procedure TCustomCheckGroup.SetCheckEnabled(Index: integer;
    @@ -189,7 +269,8 @@
     begin
       if (Index < -1) or (Index >= FItems.Count) then
         RaiseIndexOutOfBounds(Index);
    -  TCheckBox(FButtonList[Index]).Enabled:=AValue;
    +  //TCheckBox(FButtonList[Index]).Enabled:=AValue;
    +  TCheckBox(FItems.Objects[Index]).Enabled := AValue;
     end;
     
     procedure TCustomCheckGroup.SetColumnLayout(const AValue: TColumnLayout);
    @@ -207,7 +288,8 @@
     begin
       if (Index < -1) or (Index >= FItems.Count) then
         RaiseIndexOutOfBounds(Index);
    -  Result:=TCheckBox(FButtonList[Index]).Checked;
    +  //Result:=TCheckBox(FButtonList[Index]).Checked;
    +  Result := TCheckBox(FItems.Objects[Index]).Checked;
     end;
     
     procedure TCustomCheckGroup.SetChecked(Index: integer; const AValue: boolean);
    @@ -215,11 +297,14 @@
       if (Index < -1) or (Index >= FItems.Count) then
         RaiseIndexOutOfBounds(Index);
       // disable OnClick
    -  TCheckBox(FButtonList[Index]).OnClick:=nil;
    +  //TCheckBox(FButtonList[Index]).OnClick:=nil;
    +  TCheckBox(FItems.Objects[Index]).OnClick := nil;
       // set value
    -  TCheckBox(FButtonList[Index]).Checked:=AValue;
    +  //TCheckBox(FButtonList[Index]).Checked:=AValue;
    +  TCheckBox(FItems.Objects[Index]).Checked := AValue;
       // enable OnClick
    -  TCheckBox(FButtonList[Index]).OnClick:=@Clicked;
    +  //TCheckBox(FButtonList[Index]).OnClick:=@Clicked;
    +  TCheckBox(FItems.Objects[Index]).OnClick := @Clicked;
     end;
     
     procedure TCustomCheckGroup.SetItems(Value: TStrings);
    @@ -227,7 +312,7 @@
       if (Value <> FItems) then
       begin
         FItems.Assign(Value);
    -    UpdateItems;
    +    //UpdateItems;
         UpdateControlsPerLine;
       end;
     end;
    @@ -292,7 +377,7 @@
     procedure TCustomCheckGroup.Loaded;
     begin
       inherited Loaded;
    -  UpdateItems;
    +  //UpdateItems;
     end;
     
     procedure TCustomCheckGroup.DoOnResize;
    
    cg-alternative.diff (6,146 bytes)

Activities

Risk

2013-07-17 09:46

reporter  

List index.zip (128,892 bytes)

Vojtech Cihak

2013-07-17 11:35

reporter   ~0068895

I can reproduce in Qt. When I try separate the code from demo to more lines + get output:
CheckGroup1.Items.BeginUpdate;
  try
    for I := 0 to 10 do
    begin
      writeln(inttostr(CheckGroup1.Items.Add(IntToStr(I)))); //writes 0
      writeln(CheckGroup1.Items.Count); //writes 1
      CheckGroup1.Checked[I]; //HERE: ListIndex(0) out of bounds
    end;
  finally
    CheckGroup1.Items.EndUpdate;
  end;

it writes correctly 0, 1 but then it raises the exception.

Juha Manninen

2013-07-17 14:05

developer   ~0068901

This works:

  CheckGroup1.Items.BeginUpdate;
  try
    for I := 0 to 10 do // Add
      CheckGroup1.Items.Add(IntToStr(I));
  finally
    CheckGroup1.Items.EndUpdate;
  end;
  for I := 0 to 10 do // Read
    b := CheckGroup1.Checked[I];

Why do you need to read checked state inside BeginUpdate / EndUpdate?
I don't know if this is a bug or a feature. Somebody with LCL knowledge may know.

Risk

2013-07-17 15:05

reporter   ~0068905

Last edited: 2013-07-17 15:12

View 2 revisions

I was just playing around and came across this error.I am not reading I am creating new checked items that are checked if they are meant to be. I just normalized the code to make it Reproducible.

Juha Manninen

2013-07-17 20:46

developer   ~0068916

You wanted to do this:

  CheckGroup1.Items.BeginUpdate;
  try
    for I := 0 to 10 do begin // Add
      CheckGroup1.Items.Add(IntToStr(I));
      CheckGroup1.Checked[I] := True;
    end;
  finally
    CheckGroup1.Items.EndUpdate;
  end;

Ok, it gives the same error. It should not.

Bart Broersma

2013-09-01 13:24

developer   ~0069626

CheckBoxes are added to/deleted form FButtonList in UpdateItems.
UpdateItems is only called in ItemsChanged.
ItemsChanged is TStringList(FItems).OnChange.
Items.BeginUpdate suppresses TStringList(FItems).OnChange.
Therefore CheckBoxes are only added after the EndUpdate and a call to Checked inside BeginUpdate/EndUpdate tries to access an invalid Item of FButtonList.

Bart Broersma

2013-09-01 13:30

developer   ~0069627

Maybe we need to override Insert/Delete/Exchange?
(Exchange now only exchanges captions, not the corresponding checkbox, whic is a little bit weird IMHO).

Juha Manninen

2013-09-02 09:38

developer   ~0069649

> (Exchange now only exchanges captions, not the corresponding checkbox, whic is a little bit weird IMHO

Right, it sounds like another related bug.

Bart Broersma

2013-09-02 11:55

developer   ~0069655

First it should be investigated what Delphi does in Exchange...

Bart Broersma

2013-09-03 16:04

developer   ~0069695

My Delphi (3 Pro, 7PE) does not have TCheckGroup.
In TRadioGroup Items.Exchange only exchanges captions though (ugly...).
So for compatibility reasons we probably should not change that.

Bart Broersma

2013-09-03 16:14

developer   ~0069696

BTW: TRadioGroup has the same problem (when trying to add and set itemindex in beginupdate/endupdate).

Bart Broersma

2013-09-03 16:49

developer  

cg.diff (1,795 bytes)
Index: lcl/include/customcheckgroup.inc
===================================================================
--- lcl/include/customcheckgroup.inc	(revision 42575)
+++ lcl/include/customcheckgroup.inc	(working copy)
@@ -14,15 +14,39 @@
 
 { TCustomCheckGroup }
 
+type
+
+  { TCheckGroupStringList }
+
+  TCheckGroupStringList = class(TStringList)
+  protected
+    procedure Changed; override;
+  public
+    property UpdateCount;
+  end;
+
+{ TCheckGroupStringList }
+
+procedure TCheckGroupStringList.Changed;
+begin
+  if (UpdateCount = 0)
+    then inherited Changed
+  else
+  begin
+    //we always need to update the associate checkboxes (Issue #0024753)
+    if Assigned(OnChange) then OnChange(Self);
+  end;
+end;
+
 constructor TCustomCheckGroup.Create(TheOwner: TComponent);
 begin
   inherited Create(TheOwner);
   FCreatingWnd := false;
   ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents, csSetCaption,
                                   csDoubleClicks];
-  FItems      := TStringList.Create;
+  FItems      := TCheckGroupStringList.Create;
   //TStringList(FItems).OnChanging := @ItemsChanged;
-  TStringList(FItems).OnChange := @ItemsChanged;
+  TCheckGroupStringList(FItems).OnChange := @ItemsChanged;
   FButtonList := TList.Create;
   FColumnLayout := clHorizontalThenVertical;
   FColumns  := 1;
@@ -47,8 +71,12 @@
 procedure TCustomCheckGroup.ItemsChanged(Sender: TObject);
 begin
   UpdateItems;
-  UpdateControlsPerLine;
-  OwnerFormDesignerModified(Self);
+  if (TCheckGroupStringList(FItems).UpdateCount = 0) then
+  begin
+    //only do visual updates when Items is not in BeginUpdate/EndUpdate
+    UpdateControlsPerLine;
+    OwnerFormDesignerModified(Self);
+  end;
 end;
 
 procedure TCustomCheckGroup.ItemKeyDown(Sender: TObject; var Key: Word;
cg.diff (1,795 bytes)

Bart Broersma

2013-09-03 16:51

developer   ~0069698

Last edited: 2013-09-03 16:52

View 2 revisions

Target 1.2 for review of patch.
(I find my patch rather hackish, so I did not commit it yet.)

Bart Broersma

2013-09-07 19:24

developer   ~0069786

A different solution would be to store the checkboxes inside the (derived) TStringList. Override it's Insert() method to also insert a CheckBox and let the StringList own the objects. This way the nr. of items can never be out of sync with the nr. of checkboxes.
(As a side effect an Items.Exchange would also exchange the attached CheckBox, including it's Checked status).

Bart Broersma

2013-09-07 20:47

developer  

cg-alternative.diff (6,146 bytes)
Index: lcl/include/customcheckgroup.inc
===================================================================
--- lcl/include/customcheckgroup.inc	(revision 42575)
+++ lcl/include/customcheckgroup.inc	(working copy)
@@ -12,6 +12,83 @@
  *****************************************************************************
 }
 
+Type
+
+  { TCheckGroupStringList }
+
+  TCheckGroupStringList = Class(TStringList)
+  private
+    FCheckGroup: TCustomCheckGroup;
+    function CreateCheckBox: TCheckBox;
+    procedure PrepareCheckBox(CB: TCheckBox);
+  protected
+    procedure InsertItem(Index: Integer; const S: string); override;
+    procedure InsertItem(Index: Integer; const S: string; O: TObject); override;
+  public
+    constructor Create(TheOwner: TCustomCheckGroup);
+    function AddObject(const S: string; AObject: TObject): Integer; override;
+  end;
+
+{ TCheckGroupStringList }
+
+function TCheckGroupStringList.CreateCheckBox: TCheckBox;
+var
+  CheckBox: TCheckBox;
+begin
+  CheckBox := TCheckBox.Create(FCheckGroup);
+  PrepareCheckBox(CheckBox);
+  Result := CheckBox;
+end;
+
+procedure TCheckGroupStringList.PrepareCheckBox(CB: TCheckBox);
+begin
+  with CB do begin
+    Name:='CheckBox'+IntToStr(Self.Count);
+    AutoSize := False;
+    BorderSpacing.CellAlignHorizontal:=ccaLeftTop;
+    BorderSpacing.CellAlignVertical:=ccaCenter;
+    Parent := FCheckGroup;
+    OnClick := @FCheckGroup.Clicked;
+    OnKeyDown :=@FCheckGroup.ItemKeyDown;
+    OnKeyUp := @FCheckGroup.ItemKeyUp;
+    OnKeyPress := @FCheckGroup.ItemKeyPress;
+    OnUTF8KeyPress := @FCheckGroup.ItemUTF8KeyPress;
+    ParentFont := true;
+    ControlStyle := ControlStyle + [csNoDesignSelectable];
+  end;
+
+end;
+
+procedure TCheckGroupStringList.InsertItem(Index: Integer; const S: string);
+begin
+  inherited InsertItem(Index, S, CreateCheckBox);
+end;
+
+procedure TCheckGroupStringList.InsertItem(Index: Integer; const S: string;
+  O: TObject);
+begin
+  if not (O is TCheckBox) then Raise Exception.Create('Thou shalt not insert Objects into TCheckGroup.Items');
+  inherited InsertItem(Index, S, O);
+  TCheckBox(O).Parent := FCheckGroup;
+end;
+
+constructor TCheckGroupStringList.Create(TheOwner: TCustomCheckGroup);
+begin
+  FCheckGroup := TheOwner;
+end;
+
+function TCheckGroupStringList.AddObject(const S: string; AObject: TObject
+  ): Integer;
+begin
+  //Called by Assign
+  if (AObject = nil) then AObject := CreateCheckBox;
+  if not (AObject is TCheckBox) then Raise Exception.Create('Thou shalt not insert Objects into TCheckGroup.Items.');
+  PrepareCheckBox(TCheckBox(AObject));
+  Result:=inherited AddObject(S, AObject);
+  TCheckBox(AObject).Parent := FCheckGroup;
+end;
+
+
 { TCustomCheckGroup }
 
 constructor TCustomCheckGroup.Create(TheOwner: TComponent);
@@ -20,10 +97,11 @@
   FCreatingWnd := false;
   ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents, csSetCaption,
                                   csDoubleClicks];
-  FItems      := TStringList.Create;
-  //TStringList(FItems).OnChanging := @ItemsChanged;
-  TStringList(FItems).OnChange := @ItemsChanged;
-  FButtonList := TList.Create;
+  FItems      := TCheckGroupStringList.Create(Self);
+  TCheckGroupStringList(FItems).OwnsObjects := True;
+  //TCheckGroupStringList(FItems).OnChanging := @ItemsChanged;
+  TCheckGroupStringList(FItems).OnChange := @ItemsChanged;
+//  FButtonList := TList.Create;
   FColumnLayout := clHorizontalThenVertical;
   FColumns  := 1;
   FAutoFill := true;
@@ -40,13 +118,13 @@
 destructor TCustomCheckGroup.Destroy;
 begin
   FreeAndNil(FItems);
-  FreeAndNil(FButtonList);
+//  FreeAndNil(FButtonList);
   inherited Destroy;
 end;
 
 procedure TCustomCheckGroup.ItemsChanged(Sender: TObject);
 begin
-  UpdateItems;
+  //UpdateItems;
   UpdateControlsPerLine;
   OwnerFormDesignerModified(Self);
 end;
@@ -105,7 +183,8 @@
 var
   Index: Integer;
 begin
-  Index:=FButtonList.IndexOf(Sender);
+  //Index:=FButtonList.IndexOf(Sender);
+  Index := FItems.IndexOfObject(Sender);
   if Index<0 then exit;
   DoClick(Index);
 end;
@@ -181,7 +260,8 @@
 begin
   if (Index < -1) or (Index >= FItems.Count) then
     RaiseIndexOutOfBounds(Index);
-  Result:=TCheckBox(FButtonList[Index]).Enabled;
+  //Result:=TCheckBox(FButtonList[Index]).Enabled;
+  Result := TCheckBox(FItems.Objects[Index]).Enabled;
 end;
 
 procedure TCustomCheckGroup.SetCheckEnabled(Index: integer;
@@ -189,7 +269,8 @@
 begin
   if (Index < -1) or (Index >= FItems.Count) then
     RaiseIndexOutOfBounds(Index);
-  TCheckBox(FButtonList[Index]).Enabled:=AValue;
+  //TCheckBox(FButtonList[Index]).Enabled:=AValue;
+  TCheckBox(FItems.Objects[Index]).Enabled := AValue;
 end;
 
 procedure TCustomCheckGroup.SetColumnLayout(const AValue: TColumnLayout);
@@ -207,7 +288,8 @@
 begin
   if (Index < -1) or (Index >= FItems.Count) then
     RaiseIndexOutOfBounds(Index);
-  Result:=TCheckBox(FButtonList[Index]).Checked;
+  //Result:=TCheckBox(FButtonList[Index]).Checked;
+  Result := TCheckBox(FItems.Objects[Index]).Checked;
 end;
 
 procedure TCustomCheckGroup.SetChecked(Index: integer; const AValue: boolean);
@@ -215,11 +297,14 @@
   if (Index < -1) or (Index >= FItems.Count) then
     RaiseIndexOutOfBounds(Index);
   // disable OnClick
-  TCheckBox(FButtonList[Index]).OnClick:=nil;
+  //TCheckBox(FButtonList[Index]).OnClick:=nil;
+  TCheckBox(FItems.Objects[Index]).OnClick := nil;
   // set value
-  TCheckBox(FButtonList[Index]).Checked:=AValue;
+  //TCheckBox(FButtonList[Index]).Checked:=AValue;
+  TCheckBox(FItems.Objects[Index]).Checked := AValue;
   // enable OnClick
-  TCheckBox(FButtonList[Index]).OnClick:=@Clicked;
+  //TCheckBox(FButtonList[Index]).OnClick:=@Clicked;
+  TCheckBox(FItems.Objects[Index]).OnClick := @Clicked;
 end;
 
 procedure TCustomCheckGroup.SetItems(Value: TStrings);
@@ -227,7 +312,7 @@
   if (Value <> FItems) then
   begin
     FItems.Assign(Value);
-    UpdateItems;
+    //UpdateItems;
     UpdateControlsPerLine;
   end;
 end;
@@ -292,7 +377,7 @@
 procedure TCustomCheckGroup.Loaded;
 begin
   inherited Loaded;
-  UpdateItems;
+  //UpdateItems;
 end;
 
 procedure TCustomCheckGroup.DoOnResize;
cg-alternative.diff (6,146 bytes)

Bart Broersma

2013-09-07 20:49

developer   ~0069787

Alternative patch (cg-alternative) contains proof of concept for alternative proposal in note 0069786.

Bart Broersma

2013-09-13 16:49

developer   ~0070006

Applied slighly modofied version of first patch.
The second one is incomaptible with Delphi.
Please close if OK.

Issue History

Date Modified Username Field Change
2013-07-17 09:46 Risk New Issue
2013-07-17 09:46 Risk File Added: List index.zip
2013-07-17 11:35 Vojtech Cihak Note Added: 0068895
2013-07-17 14:05 Juha Manninen Note Added: 0068901
2013-07-17 15:05 Risk Note Added: 0068905
2013-07-17 15:12 Risk Note Edited: 0068905 View Revisions
2013-07-17 20:46 Juha Manninen Note Added: 0068916
2013-07-17 20:47 Juha Manninen LazTarget => -
2013-07-17 20:47 Juha Manninen Assigned To => Juha Manninen
2013-07-17 20:47 Juha Manninen Status new => confirmed
2013-07-17 20:53 Juha Manninen Assigned To Juha Manninen =>
2013-09-01 13:24 Bart Broersma Note Added: 0069626
2013-09-01 13:30 Bart Broersma Note Added: 0069627
2013-09-02 09:38 Juha Manninen Note Added: 0069649
2013-09-02 11:55 Bart Broersma Note Added: 0069655
2013-09-03 16:04 Bart Broersma Note Added: 0069695
2013-09-03 16:14 Bart Broersma Note Added: 0069696
2013-09-03 16:49 Bart Broersma File Added: cg.diff
2013-09-03 16:51 Bart Broersma LazTarget - => 1.2
2013-09-03 16:51 Bart Broersma Note Added: 0069698
2013-09-03 16:51 Bart Broersma Target Version => 1.2.0
2013-09-03 16:52 Bart Broersma Note Edited: 0069698 View Revisions
2013-09-07 19:24 Bart Broersma Note Added: 0069786
2013-09-07 20:47 Bart Broersma File Added: cg-alternative.diff
2013-09-07 20:49 Bart Broersma Note Added: 0069787
2013-09-13 16:49 Bart Broersma Fixed in Revision => r42772
2013-09-13 16:49 Bart Broersma Note Added: 0070006
2013-09-13 16:49 Bart Broersma Status confirmed => resolved
2013-09-13 16:49 Bart Broersma Resolution open => fixed
2013-09-13 16:49 Bart Broersma Assigned To => Bart Broersma
2013-09-13 16:59 Bart Broersma Fixed in Revision r42772 => r42772, r42774
2013-09-13 16:59 Bart Broersma Fixed in Version => 1.1 (SVN)