【发布时间】:2015-10-24 02:40:27
【问题描述】:
我在 Firemonkey 中使用 TListBox,在动态显示/隐藏项目时遇到了一个奇怪的问题。这包括德尔福 XE7 和 XE8。设置,在表单顶部有一个TPopupBox,用户在其中选择列出的项目之一。根据所选择的,TListBox 应该只显示某些TListBoxItems,并隐藏其余部分。其中一部分包括在不可见时将每个列表项的高度调整为 0(否则会在项目之间留下难看的间隙)。
问题在于,非常随机且自发地(无模式)在此 TPopupBox 中选择一个项目(调用 OnChange 修改可见性)会在未知点产生 EArgumentOutOfRangeException。代码在第一行调用CheckItemRangeInline(AIndex); 中的System.Generics.Collections.TListHelper.SetItemN() 中断,在那里,它很简单:
procedure TListHelper.CheckItemRangeInline(AIndex: Integer);
begin
if (AIndex < 0) or (AIndex >= FCount) then
raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
end;
异常继续一遍又一遍地引发,没有结束(从连续 4 个开始)。当我使用调试器介入时,我永远无法让它发生。
这里使用了几个常用的过程来控制项目的可见性:
//lstTrans = TListBox
//Iterates through all items and hides everything
procedure TfrmMain.HideTransItems;
var
X: Integer;
begin
for X := 0 to lstTrans.Count-1 do begin
lstTrans.ListItems[X].Visible:= False;
end;
end;
//Sets height of visible items to 42, invisible items to 0
procedure TfrmMain.ResetTransHeights;
var
X: Integer;
LI: TListBoxItem;
begin
for X := 0 to lstTrans.Count-1 do begin
LI:= lstTrans.ListItems[X];
if LI.Visible then
LI.Height:= 42
else
LI.Height:= 0;
end;
end;
然后,在选择@ 987654333中的某些内容时:
//cboTrans = TPopupBox
procedure TfrmMain.cboTransChange(Sender: TObject);
procedure E(AItem: TListBoxItem);
begin
AItem.Visible:= True;
end;
begin
HideTransItems; //Make all list items invisible
case cboTrans.ItemIndex of
0: begin
E(lbSomeListBoxItem);
E(lbSomeOtherItem);
//More calls to "E"
end;
1: begin
E(lbSomeListBoxItem2);
//More calls to "E"
end;
//More indexes
end;
ResetTransHeights; //Adjust visible list item heights to be seen
end;
(完整的过程只是很多完全相同类型的调用,这里就不多说了)
- 我没有在任何地方添加或删除项目 - 只是更改可见性
- 没有触发可能导致某些错误循环的事件
-
TPopupBox位于TListBox之外 - 每个
TListBoxItem都有一个或两个控件(但显示/隐藏哪些控件并不重要) - 在此
TPopupBox中选择一个项目可能一次可行,但下一次失败 - 有时它会在我第一次显示/隐藏这些项目时发生,有时需要 20-30 次尝试
- 在调试中单步执行时无法重现
为什么我会收到此异常,我该如何解决?
【问题讨论】:
-
您是否对 D10Seattle 进行了同样的尝试? TList 中存在一些错误。
-
更多关于 TList 中错误的信息:plus.google.com/103246155735524926641/posts/Yne5Nv6mp6B
-
@LURD 我还没有尝试过 10,但是当我开始遇到这个问题时,我最初是在 XE7 中工作的。
TList<T>错误显然出现在 XE8 中。 -
一个看起来有效的丑陋解决方法是,我没有将高度设置为
0,而是将它们设置为0.01。 -
几个小时没有问题后,我将其改回
0,然后又开始了。否则这里根本没有模式。
标签: delphi listbox delphi-xe7 delphi-xe8