Search code examples
delphidelphi-10.4-sydney

TControlList scrolls list when a record is changed when using LiveBindings


To reproduce: Set up a TControlList with LiveBindings to a DataSet and assign an OnClick event that just does:

DataSet.Edit;
DataSet.Post;

Now when you click on a cell it will scroll that cell to be in the last row of the list (assuming you've already scrolled down far enough).

This is probably a bug, but is there a way I can prevent the repositioning of the visible items in the list?

Using Delphi 10.4.2


Solution

  • I couldn't find a "nice" solution to this, so I went down the RTTI route. We need to access the private FScrollPos field, remember what it is before we change a record in the dataset, then reset it back.

    procedure TForm7.ControlList1Click(Sender: TObject);
    var
      OldScrollPos : integer;
    begin
      inherited;
      OldScrollPos := TRttiContext.Create.GetType(TControlList).GetField('FScrollPos').GetValue(Sender).AsInteger;
      DataSet.Edit;
      DataSet.Post;
      TRttiContext.Create.GetType(TControlList).GetField('FScrollPos').SetValue(Sender, OldScrollPos);
    end;
    

    This removes the "scroll item to the bottom row" behaviour when we alter a record. You will need to add System.RTTI to your uses.