如何防止listview跳至item.count更改的选定行/重点行?

时间:2018-09-27 09:28:33

标签: listview delphi vcl delphi-10.2-tokyo

我有一个虚拟的列表视图,我打算用它来显示相当大的日志文件中的内容。

每当添加或删除一行并且我在列表框中选择了一行或将其放在焦点(或两者都选中)时,它将自动滚动回到该行,这很烦人。

在修改商品计数时,感觉就像是在调用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;

编辑:测试不同的ViewStyle,这仅在vsReport和vsList中发生

1 个答案:

答案 0 :(得分:4)

问题在于TListItems.Count属性设置程序调用{​​{3}}而没有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;

这就是为什么Count更改时ListView就会滚动的原因。您必须直接直接致电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;