Firemonkey ListView项目索引未更新

时间:2015-06-15 17:04:04

标签: delphi listview firemonkey

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

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';

然后,我在第一个(项目)标题下面添加了一些项目,这样可以正常工作。

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

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

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

这应该是在Payments Header上方添加项目(Charges部分的最后一项)。但是,它会在列表中进一步添加(在索引2处)。

在调试此问题时,令人惊讶的是3个标题'添加项目后索引尚未更新。以下代码演示了:

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;

...强制将该特定项目重新编入索引。

虽然从技术上说这是有效的,但这是一个非常草率的解决方法。我还能做些什么来确保在插入项目之前重新索引此列表视图?

注意:当我使用TListBox执行类似方法时,我没有遇到此问题。它肯定是TListView控件中的错误。我不是在问如何解决这个问题,而是为了更好的解决方法。

注意:这种解决方法似乎只能工作一次或两次 - 进一步尝试,甚至这种解决办法也不会强制重新索引。

更新

这似乎是唯一神奇的解决方法,但仍然非常草率:

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

2 个答案:

答案 0 :(得分:1)

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

了解有关bug的更多信息: Delphi XE8 bug in TList<T>, need workaround

真的看起来像个臭虫。在Win32和Win64下使用Delphi XE8进行测试。

方法.AddItem.Insert

具有相同的效果

外观如何:

enter image description here

它应该如何(以及如果你使用LV.Items[1].Index它看起来如何)。注意:如果事先添加&#34;费用&#34;你将选择TListView中的任何项目

enter image description here

答案 1 :(得分:0)

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

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

在幕后,有a known bug in the generic TList实施,特别是与Insert功能的错误实施。我还没有确认是否是这种情况,但这种解决办法至少可以解决这个问题。