【问题标题】:Firemonkey ListView item indexes not updatingFiremonkey ListView 项目索引未更新
【发布时间】: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);

索引是 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;

【问题讨论】:

    标签: delphi listview firemonkey


    【解决方案1】:

    这是 Delphi XE8 中的错误。在 Delphi XE7 Update 1 中运行良好。

    阅读更多关于错误的信息: Delphi XE8 bug in TList<T>, need workaround


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

    方法.AddItem.Insert效果一样

    外观:

    它应该是怎样的(如果你使用LV.Items[1].Index,它看起来会怎样)。注意:如果事先在“费用”下添加项目,您将选择 TListView 中的任何项目,效果相同

    【讨论】:

    • 我相信问题更早,在使用Insert 时,它似乎没有更新索引。
    【解决方案2】:

    虽然真正的解决办法是在 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 函数的失误。我尚未确认是否是这种情况,但这种解决方法至少可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 2017-08-12
      • 2018-08-15
      • 1970-01-01
      • 2013-01-28
      相关资源
      最近更新 更多