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);
索引是 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;
...强制该特定项目为 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
函数的错误。我还没有确认是否是这种情况,但这个解决方法至少可以解决问题。
我在 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);
索引是 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;
...强制该特定项目为 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
函数的错误。我还没有确认是否是这种情况,但这个解决方法至少可以解决问题。