Как предотвратить просмотр списка при переходе на выбранную / выделенную строку при изменении item.count? - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть виртуальный просмотр списка, который я планирую использовать для отображения объектов из довольно большого файла журнала.

Каждый раз, когда строка добавляется или удаляется, и у меня выбирается или фокусируется строка (илиоба) в списке, он автоматически прокручивает назад к нему, что очень раздражает.

Чувствуется, что что-то делает вызов для MakeVisible (или что-то, что делает то же самое), когда изменяется количество элементов.

Очень упрощенный пример для его воспроизведения:

procedure TForm1.FormCreate(Sender: TObject);
var
  Col: TListColumn;
begin
  ListView1.OwnerData := True;
  ListView1.ViewStyle := vsReport;
  ListView1.RowSelect := True;

  Col := ListView1.Columns.Add;
  Col.Caption := 'LineNum';
  Col.Alignment := taLeftJustify;
  Col.Width := 70;
end;
// listview onData event
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := IntToStr(Item.Index+1);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  ListView1.Items.Count := ListView1.Items.Count + 10;
end;

Редактировать: Тестирование разных ViewStyles, это происходит только с vsReport и vsList

1 Ответ

0 голосов
/ 27 сентября 2018

Проблема в том, что установщик свойства TListItems.Count вызывает ListView_SetItemCountEx() без флага LVSICF_NOSCROLL:

Элемент управления просмотра списка не будет изменять позицию прокруткипри изменении количества элементов.

procedure TListItems.SetCount(Value: Integer);
begin
  if Value <> 0 then
    ListView_SetItemCountEx(Handle, Value, LVSICF_NOINVALIDATEALL)
  else
    ListView_SetItemCountEx(Handle, Value, 0);
end;

Именно поэтому ListView прокручивает каждый раз, когда изменяется Count.Вам придется напрямую позвонить ListView_SetItemCountEx(), чтобы вы могли указать флаг LVSICF_NOSCROLL.

uses
  ..., CommCtrl;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //ListView1.Items.Count := ListView1.Items.Count + 10;
  ListView_SetItemCountEx(ListView1.Handle, ListView1.Items.Count + 10, LVSICF_NOINVALIDATEALL or LVSICF_NOSCROLL);
end;
...