如何重建一个TListView但保留滚动信息? [英] How to rebuild a TListView but keep the scroll information?

查看:86
本文介绍了如何重建一个TListView但保留滚动信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TListView中有一个错误:当您处于设置了GroupViewvsReport模式并尝试插入项目时,该项目显示在组中的最后位置,而不是您插入的位置.问题在

In TListView there is a bug: when you are in vsReport mode with GroupView set and try to insert a item, it is displayed last in the group not where you inserted. The problem is debated here. There are a few answers but none of them work. So, I think the only solution is to rebuild the entire list every time you insert a item. It's not simple but I think I can do it. But there is a big problem. If the scroll window is in the middle of the list and I rebuild the list, it send me back to the begining. It is possible to keep somehow the scroll information ?

我尝试过:

procedure TNutrientsForm.Button2Click(Sender: TObject);
var ix,iy:Integer;
begin
 ix:= NList.ViewOrigin.X;
 iy:= NList.ViewOrigin.Y;
 NList.Items.BeginUpdate;
 RefreshList;
 NList.Scroll(ix, iy);
 NList.Items.EndUpdate;
end;

...但是在vsReport模式下,您只能滚动行高的倍数,因此它无法将我精确定位在应该的位置.

... but in vsReport mode you can only scroll in multiple of row height, so it does not position me exactly where it is supposed to.

无论如何,如果您也对上面的链接中的问题有答案,可以将其发布在这里,我会很高兴.我为此工作了3天,但没有找到解决方案.这个问题已经9岁了.也许我们可以再试一次.

推荐答案

如何将插入的项目移动到正确的位置?

实际上没有必要 重建列表视图 来解决 LVM_INSERTITEM 消息).

How to move inserted items to the correct position?

There's actually no need to rebuild list view to workaround the original issue. It's the problem of the Windows list view control (it can be reproduced even when inserting items in a raw API way by using the LVM_INSERTITEM message, for example).

幸运的是,Delphi列表视图项对象具有正确的索引值(控件中预期位置的索引值),因此剩下的就是由它们对Windows控件中的项进行重新排序.这可以通过自定义排序来完成.例如,您可以编写这样的帮助方法:

Luckily, Delphi list view item objects are holding correct index values (of the intended placement in the control), so what remains is reordering the items in the Windows control by them. And that can be done by custom sorting. For example you can write a helper method like this:

type
  TListViewHelper = class helper for TListView
  public
    function FixItemsOrder: Boolean;
  end;

function FixComparer(lParam1, lParam2, lParamSort: LPARAM): Integer; stdcall;
begin
  Result := TListItem(lParam1).Index - TListItem(lParam2).Index;
end;

function TListViewHelper.FixItemsOrder: Boolean;
begin
  Result := Boolean(SendMessage(Handle, LVM_SORTITEMS, 0, LPARAM(@FixComparer)));
end;

每当您插入一个(或多个)项目时,请调用以下方法:

And whenever you insert an item (or multiple items), call such method:

var
  ListItem: TListItem;
begin
  ListView1.Items.BeginUpdate;
  try
    ListItem := ListView1.Items.Insert(0);
    ListItem.Caption := 'Item 1';
    ListItem.GroupID := 0;

    ListItem := ListView1.Items.Insert(0);
    ListItem.Caption := 'Item 2';
    ListItem.GroupID := 0;

    ListItem := ListView1.Items.Insert(0);
    ListItem.Caption := 'Item 3';
    ListItem.GroupID := 0;

    ListView1.FixItemsOrder;
  finally
    ListView1.Items.EndUpdate;
  end;
end;

这篇关于如何重建一个TListView但保留滚动信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆