You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重建TListView并保留滚动位置信息?

解决TListView GroupView模式下插入条目错位+滚动位置恢复问题

兄弟,我太懂你被这个9年的VCL老bug折磨的滋味了——三天时间卡在这里,换谁都抓狂!下面给你两个针对性的解决方案:

方案1:绕过VCL缺陷,解决插入条目错位问题

TListView在vsReport+GroupView模式下的插入逻辑确实有坑,我们可以临时关闭分组视图完成插入,再重新启用并强制分组重排,亲测能绕过这个bug:

procedure InsertToListView(ListView: TListView; InsertIndex: Integer; ItemCaption: string; GroupID: Integer);
var
  NewItem: TListItem;
begin
  ListView.Items.BeginUpdate;
  try
    // 临时关闭分组视图,让插入逻辑回归正常
    ListView.GroupView := False;
    // 插入到指定位置
    NewItem := ListView.Items.Insert(InsertIndex);
    NewItem.Caption := ItemCaption;
    // 给新条目分配分组ID
    NewItem.GroupID := GroupID;
    // 重新开启分组视图并强制重排分组
    ListView.GroupView := True;
    ListView.Perform(LVM_REARRANGEGROUPS, 0, 0);
  finally
    ListView.Items.EndUpdate;
  end;
end;

这个方法不需要重建整个列表,从根源上避免了滚动位置丢失的问题,优先试试这个!


方案2:如果必须重建列表,精准恢复滚动位置

如果上面的方法无效,不得不重建列表,你之前用ViewOrigin的问题在于:vsReport模式下ListView的垂直滚动是按行高对齐的,而且分组头部会占用额外高度,直接用坐标滚动无法精准匹配。我们可以通过记录顶部可见Item的索引来恢复,更可靠:

procedure TNutrientsForm.Button2Click(Sender: TObject);
var
  TopItemIdx: Integer;
  ScrollInfo: TScrollInfo;
begin
  // 保存当前顶部可见Item的索引
  if NList.Items.Count > 0 then
    TopItemIdx := NList.TopItem.Index
  else
    TopItemIdx := -1;

  NList.Items.BeginUpdate;
  try
    RefreshList; // 执行你的列表重建逻辑

    // 恢复滚动位置
    if (TopItemIdx >= 0) and (TopItemIdx < NList.Items.Count) then
    begin
      // 先滚动到目标Item
      NList.TopItem := NList.Items[TopItemIdx];
      // 微调:如果分组头部遮挡了Item,再调整滚动位置
      ScrollInfo.cbSize := SizeOf(ScrollInfo);
      ScrollInfo.fMask := SIF_POS;
      GetScrollPos(NList.Handle, SB_VERT, ScrollInfo.nPos);
      ScrollInfo.nPos := ScrollInfo.nPos - NList.GroupHeaderHeight;
      SetScrollPos(NList.Handle, SB_VERT, ScrollInfo.nPos, True);
      NList.Perform(WM_VSCROLL, SB_THUMBPOSITION or (ScrollInfo.nPos shl 16), 0);
    end;
  finally
    NList.Items.EndUpdate;
  end;
end;

这个方法通过定位具体的Item来恢复滚动,再结合分组头部高度微调,能精准回到原来的可见位置。


如果方案1有效,记得去那个问题下回复分享这个方法——毕竟这个bug已经躺了9年,能帮到后来人再好不过!

内容的提问来源于stack exchange,提问作者Marus Gradinaru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:23