动态创建ListBoxItem中Layout内Label文本修改报错求助
解决ListBoxItem嵌套Layout遍历Label时的索引越界问题
问题根源
你代码里的absolute关键字是引发错误的核心原因:layout : TLayout absolute Ctrl; 和 Lbl : TLabel absolute Ctrl; 意味着layout、Lbl和Ctrl是同一内存地址的变量别名。当你在内层循环执行Ctrl:=layout.Controls[e];时,Ctrl指向了布局内的Label控件,同时layout也会被强制转换成这个Label类型,此时layout.ControlsCount不再是原来的4(而是Label控件的子控件数量,通常为0)。当循环到e=1时,尝试访问layout.Controls[1]自然会触发"Argument out of range"错误。
修复代码
移除absolute关键字,改用独立变量和类型安全转换:
var e, h : integer; item : TListBoxItem; Ctrl: TControl; targetLayout: TLayout; Lbl : TLabel; begin item := ListBox1.ListItems[itemNum]; // 目标ListBoxItem for h := 0 to item.ControlsCount - 1 do begin Ctrl := item.Controls[h]; if Ctrl is TLayout then begin targetLayout := Ctrl as TLayout; if targetLayout.Name = 'lout3' then // 找到名为lout3的布局 begin for e := 0 to targetLayout.ControlsCount - 1 do begin Ctrl := targetLayout.Controls[e]; if Ctrl is TLabel then begin Lbl := Ctrl as TLabel; if Lbl.Name = 'qty1' then begin if ed_pos1.Text = '' then Lbl.Text := ed_pos1.TextPrompt else Lbl.Text := ed_pos1.Text; end else if Lbl.Name = 'qty2' then begin if ed_pos2.Text = '' then Lbl.Text := ed_pos2.TextPrompt else Lbl.Text := ed_pos2.Text; end else if Lbl.Name = 'qty3' then begin if ed_pos3.Text = '' then Lbl.Text := ed_pos3.TextPrompt else Lbl.Text := ed_pos3.Text; end; end; end; end; end; end; end;
关键修改点
- 移除
absolute关键字:避免变量别名导致的意外类型覆盖,确保每个变量指向独立的控件实例 - 新增
targetLayout变量:存储找到的lout3布局控件,内层循环中始终通过这个变量访问目标布局的子控件,不会被后续Ctrl的赋值影响 - 使用
as进行类型转换:相比absolute,as是类型安全的转换方式,只有当控件确实是目标类型时才会转换成功,避免类型不匹配的潜在问题
内容的提问来源于stack exchange,提问作者Antonis
相关产品推荐
相关产品推荐

