清除前保存顶部项目,
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
获取a的'nPos' TScrollInfo
,然后发送填充后许多WM_VSCROLL
带有“SB_LINEDOWN”的消息。
保存滚动位置:
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);