Delphi – 获取并设置ListView的滚动条位置

前端之家收集整理的这篇文章主要介绍了Delphi – 获取并设置ListView的滚动条位置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这可能看起来像一个愚蠢的&简单的问题,然而,我一直无法找到令人满意的答案.基本上,我有一个带数据的TListview(style = vsReport).有时,我必须更新它,因此,我必须清除列表视图并使用更新的数据再次填充它.

但是,当我这样做时,滚动条位置重置为0.我希望能够在清除之前获得滚动条位置并将其设置回原来的状态.如果更新的数据与旧数据具有完全相同的行数,我需要滚动条与之前的位置完全相同;如果没有,我只需要它和以前在同一个地方或多或少.

看起来很简单吧?然而,我发现的只有TopItem和MakeVisible的黑客或调整.有没有适当的方法来做到这一点?

谢谢!

解决方法

清除前保存顶部项目,
FSaveTop := ListView1.TopItem;

更新后,滚动列表视图,以便保存的顶部项目的“y”位置为0(标题高度):

var
  R: TRect;
begin
  if Assigned(FSaveTop) then begin
    // account for header height
    GetWindowRect(ListView_GetHeader(ListView1.Handle),R);
    ListView1.Scroll(0,FSaveTop.Position.Y - (R.Bottom - R.Top));
  end;
end;

实际上,由于您要重新填充列表视图,因此您必须设计一种机制来查找您想要位于顶部的项目,而不是保存对它的引用.

如果你不喜欢通过’top item’修改滚动位置,因为像SetScrollInfo,SetScrollPos这样的函数不会更新控件的客户区域,你可以在清除列表之前使用GetScrollInfo来获取TScrollInfo的’nPos’,然后在填充后用’SB_LINEDOWN`发送那么多WM_VSCROLL消息.

保存滚动位置:

var
  FPos: Integer;
  SInfo: TScrollInfo;
begin
  SInfo.cbSize := SizeOf(SInfo);
  SInfo.fMask := SIF_ALL;
  GetScrollInfo(ListView1.Handle,SB_VERT,SInfo);
  FPos := SInfo.nPos;
  ...

填充后,滚动(假设滚动位置为0):

var
  R: TRect;
begin
  ...
  R := ListView1.Items[0].DisplayRect(drBounds);
  ListView1.Scroll(0,FPos * (R.Bottom - R.Top));

要么,

var
  i: Integer;
begin
  ...
  for i := 1 to FPos do
    SendMessage(ListView1.Handle,WM_VSCROLL,SB_LINEDOWN,0);

猜你在找的Delphi相关文章