You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.2.2移动平台TListBox.OnClick事件点击项索引异常

解决Delphi 10.2.2移动平台TListBox点击索引异常的问题

我之前在Delphi 10.2.2做移动项目时也踩过这个坑!问题出在FireMonkey移动框架的事件触发时序上:Windows和Mac平台的TListBox会先更新选中状态再触发OnClick,但iOS和Android是反过来的——OnClick事件先跑,这时候ItemIndex还没来得及更新,所以第一次点第一个项时拿到-1,点第二个项时拿到的是上一次选中的0。

下面给你几个靠谱的解决方案:

方案1:改用OnItemClick事件(最推荐)

FireMonkey其实给TListBox专门做了OnItemClick事件,它会直接把被点击的TListBoxItem传给你,不用依赖ItemIndex就能拿到正确的位置:

procedure TForm1.ListBox1ItemClick(const Sender: TObject; const Item: TListBoxItem);
var
  clickedIndex: Integer;
begin
  clickedIndex := ListBox1.Items.IndexOf(Item);
  ShowMessage('选中项索引:' + IntToStr(clickedIndex));
  // 或者直接操作Item,比如Item.Text获取内容
end;

这个方法完全避开了ItemIndex的时序问题,是官方设计用来处理列表项点击的正确方式。

方案2:延迟获取ItemIndex(如果必须用OnClick)

如果你的代码已经大量依赖OnClick事件不想改,可以用TThread.Queue把获取ItemIndex的逻辑延后,等UI线程完成选中状态更新后再执行:

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  TThread.Queue(nil, procedure
    var
      correctIndex: Integer;
    begin
      correctIndex := ListBox1.ItemIndex;
      ShowMessage('选中项索引:' + IntToStr(correctIndex));
    end);
end;

TThread.Queue会把代码放到UI线程的消息队列末尾,等当前的点击事件处理完、控件状态更新后再执行,这样拿到的就是正确的索引了。

方案3:升级Delphi版本

这个是底层框架的bug,官方在Delphi 10.3 Rio及以后的版本里已经修复了。如果你的项目允许升级,直接更到新版本就能彻底解决这个问题,不用改代码。

测试验证

按照上面任意一种方法修改后,在iOS和Android上测试:

  • 点击第一个ListBoxItem,会立即返回索引0
  • 点击第二个ListBoxItem,返回索引1,完全符合预期

内容的提问来源于stack exchange,提问作者Mike at Bookup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:28:08