我有一个错误的脚本:
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
for tlistitem in listview1.items do
Try
ServerSocket1.Socket.Connections[tlistitem].Sendtext('TestConnection');
except
listview1.Items.Delete(tlistitem);
end;
end;
错误在:对于listview1.items中的tlistitem,但我不知道有什么问题,有人可以帮助我吗?
答案 0 :(得分:7)
TListItem
是一种类型。您必须在循环中使用该类型的局部变量。
var
item: TListItem;
begin
for item in listView1.Items do
...
请参阅Iteration Over Containers Using For statements
。
迭代变量Element的类型必须与容器中保存的类型匹配。对于循环的每次迭代,迭代变量保存当前集合成员。与常规 for -loops一样,迭代变量必须在与 for 语句相同的块中声明。
警告:无法在循环内修改迭代变量。这包括赋值并将变量传递给过程的var参数。这样做会导致编译时警告。
如果要删除项目,则必须传递有效索引。
listView1.Items.Delete(listView1.Items.IndexOf(item));
TServerWinSocket.Connections
需要一个整数索引,因此您必须将项目转换为索引,如上所示。
如果您的目标是删除断开连接的对象,并且通过测试所有项目来实现,那么您应该使用正常的自上而下的循环进行迭代。
for i := Pred(listView1.Items.Count) downto 0 do
答案 1 :(得分:1)
此代码存在许多问题。首先,for循环需要一个本地循环变量:
var
Item: TListItem;
....
for Item in listView1.Items do
....
在整个代码中,您使用类型,其中需要变量。
您的一揽子异常处理程序很差。它会吞下所有例外。将其更改为仅处理预期的异常。
似乎不太可能
ServerSocket1.Socket.Connections[Item]
可以在您尝试时按项目编制索引。你必须在代码的这一点重新思考你的意思。
最后,作为一般规则,您不能在迭代它时修改容器。当您致电Delete
以从列表中删除项目时,即可执行此操作。我认为你需要在迭代列表时构建要删除的项目列表。然后在迭代完成后,删除项目。请注意Delete
期望索引而不是项目作为参数。
作为更一般的建议,使用GUI控件作为主要数据容器通常是个坏主意。在某个地方,这个设计决定可能会回来困扰你。