【发布时间】:2015-06-15 17:04:03
【问题描述】:
我在 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';
然后,我在第一个 (Item) 标题下方添加了一些项目,效果很好。
SomeItem:= LV.Items.Insert(FChargeHeader.Index);
然后,我希望在其他标题之一下方插入一个项目...
SomeItem:= LV.Items.Insert(FPaymentHeader.Index);
这应该在付款标题上方添加项目(费用部分中的最后一项)。但是,它反而会被添加到列表的更靠前(在索引 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;
【问题讨论】:
标签: delphi listview firemonkey