When BeginUpdate/EndUpdate is used, it persists the scroll position, but testing it here with:
procedure TForm2.Button1Click(Sender: TObject);
var
i: integer;
begin
TMSFNCTableView1.BeginUpdate;
TMSFNCTableView1.Items.Clear;
for i := 0 to 50 do
begin
TMSFNCTableView1.Items.Add.Text := 'item '+inttostr(i);
end;
TMSFNCTableView1.EndUpdate;
TMSFNCTableView1.ScrollToItem(0);
end;
scrolls back as expected to the first item