gpt4 book ai didi

listview - 如何重建 TListView 但保留滚动信息?

转载 作者:行者123 更新时间:2023-12-02 12:15:56 25 4
gpt4 key购买 nike

TListView 中存在一个错误:当您处于设置了 GroupViewvsReport 模式并尝试插入项目时,会显示该项目组中的最后一个,而不是您插入的位置。问题有争议here 。有几个答案,但没有一个有效。所以,我认为唯一的解决方案是每次插入项目时重建整个列表。这并不简单,但我想我能做到。但有一个大问题。如果滚动窗口位于列表的中间并且我重建列表,它会将我带回到开头。是否可以以某种方式保留滚动信息?

我尝试过这个:

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 模式下,您只能滚动行高的倍数,因此它无法将我准确定位在应该的位置。

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

最佳答案

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

实际上没有必要rebuild list view解决方法the original issue 。这是 Windows ListView 控件的问题(例如,即使使用 LVM_INSERTITEM 消息以原始 API 方式插入项目,也可以重现该问题)。

幸运的是,Delphi ListView 项对象保存了正确的索引值(控件中预期位置的索引值),因此剩下的就是通过它们对 Windows 控件中的项重新排序。这可以通过自定义排序来完成。例如,您可以编写如下辅助方法:

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;

每当插入一个项目(或多个项目)时,调用这样的方法:

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;

关于listview - 如何重建 TListView 但保留滚动信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50510543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com