我在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);
索引为0
,1
和2
,即使它们应该更大(添加一些项目之后)。
进一步的调试让我添加了这段代码:
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;
答案 0 :(得分:1)
这是Delphi XE8中的错误。在Delphi XE7 Update 1中正常工作。
了解有关bug的更多信息: Delphi XE8 bug in TList<T>, need workaround
真的看起来像个臭虫。在Win32和Win64下使用Delphi XE8进行测试。
方法.AddItem
与.Insert
外观如何:
它应该如何(以及如果你使用LV.Items[1].Index
它看起来如何)。注意:如果事先添加&#34;费用&#34;你将选择TListView中的任何项目
答案 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
功能的错误实施。我还没有确认是否是这种情况,但这种解决办法至少可以解决这个问题。