Firemonkey ListView 项目索引未更新

Firemonkey ListView item indexes not updating

我在 Firemonkey 中使用 TListView。在启动时,我创建了 3 个列表视图 headers 并保留对它们的引用以供将来使用(特别是在每个 header 下方插入项目)。

FItemHeader:= LV.Items.Add;
FItemHeader.Purpose:= TListItemPurpose.Header;
FItemHeader.Text:= 'Items';
FChargeHeader:= LV.Items.Add;
FChargeHeader.Purpose:= TListItemPurpose.Header;
FChargeHeader.Text:= 'Charges';
FPaymentHeader:= LV.Items.Add;
FPaymentHeader.Purpose:= TListItemPurpose.Header;
FPaymentHeader.Text:= 'Payments';

然后,我在第一个(项目)下面添加了一些项目 header,效果很好。

SomeItem:= LV.Items.Insert(FChargeHeader.Index);

然后,我希望在其他 headers 之一下面插入一个项目...

SomeItem:= LV.Items.Insert(FPaymentHeader.Index);

这应该在付款 Header(费用部分的最后一项)上方添加项目。但是,它反而被添加到列表的更上方(在索引 2 处)。

在调试这个问题的时候,意外的是3个header的索引在添加项目后没有更新。以下代码表明:

S:= 'Items: '+IntToStr(FItemHeader.Index)+sLineBreak+
  'Charges: '+IntToStr(FChargeHeader.Index)+sLineBreak+
  'Payments: '+IntToStr(FPaymentHeader.Index);
ShowMessage(S);

索引是 012,尽管它们应该更大(在添加一些项目之后)。

进一步的调试让我添加了这段代码:

for X := 0 to LV.Items.Count-1 do begin
  S:= S + LV.Items[X].Text+' - '+IntToStr(LV.Items[X].Index)+sLineBreak;
end;
ShowMessage(S);

报告所有正确的索引。此外,如果我调用第二段代码然后调用第一段代码,索引就没问题了..

for X := 0 to LV.Items.Count-1 do begin
  S:= S + LV.Items[X].Text+' - '+IntToStr(LV.Items[X].Index)+sLineBreak;
end;
ShowMessage(S);
S:= 'Items: '+IntToStr(FItemHeader.Index)+sLineBreak+
  'Charges: '+IntToStr(FChargeHeader.Index)+sLineBreak+
  'Payments: '+IntToStr(FPaymentHeader.Index);
ShowMessage(S);

所以在进一步挖掘之后,结果是一个简单的调用...

LV.Items[1].Index;

...强制该特定项目为 re-indexed。

虽然从技术上讲这是可行的,但它非常草率 work-around。我还能做些什么来确保此列表视图在插入项目之前获得 re-indexed?

注意:当我使用 TListBox 执行类似的方法时,我没有遇到这个问题。这肯定是 TListView 控件中的错误。我不是问如何修复错误,而是为了更好 work-around.

注意:这个 work-around 似乎只工作了一两次 - 进一步尝试,甚至这个 work-around 也不会强制 re-index.

更新

看来只有这个神奇了work-around,还是很马虎:

procedure ReindexListView(AListView: TListView);
var
  X: Integer;
begin
  for X := 0 to AListView.Items.Count-1 do
    AListView.Items[X].Index;
end;

这是 Delphi XE8 中的错误。在 Delphi XE7 更新 1 中工作正常。

阅读有关错误的更多信息:


看起来确实像个错误。在 Win32 和 Win64 下使用 Delphi XE8 进行测试。

方法.AddItem.Insert

效果相同

外观:

它应该如何(以及如果您使用 LV.Items[1].Index 它看起来如何)。注意:如果之前在 "Charges" 下添加项目,您将 select TListView

中的任何项目,效果相同

虽然真正的解决办法是在 Embarcadero 的球场上,但这似乎是唯一的解决方法:

procedure ReindexListView(AListView: TListView);
var
  X: Integer;
begin
  for X := 0 to AListView.Items.Count-1 do
    AListView.Items[X].Index;
end;

在幕后,有 实现,特别是 Insert 函数的错误。我还没有确认是否是这种情况,但这个解决方法至少可以解决问题。