我正在使用2个列表视图并且正在将项目从一个复制到另一个(使用下面的代码)但是当触发目标Listview的onInsert事件时,传递的Item值始终为nil而不是新移动的列表项,是否有人请指出我做错了什么?
Source.Items.BeginUpdate;
Destination.Items.BeginUpdate;
for i := Source.Items.Count - 1 downto 0 do
if Source.Items[i].Selected then
begin
Destination.Items.Add.Assign(source.Items[i]);
Source.Items[i].Delete;
end;
Source.Items.EndUpdate;
Destination.Items.EndUpdate;
由于
科林
答案 0 :(得分:5)
我无法使用OnInsert
项复制nil
。因此,我认为你的意思是,当调用OnInsert
时,Item参数不具有源项的属性(标题,数据,图像索引等..)。原因是,当调用'OnInsert'时,尚未执行赋值。
这一行
Destination.Items.Add.Assign(source.Items[i]);
类似于
var
Item: TListItem;
...
Item := Destination.Items.Add; // <- OnInsert is called here
Item.Assign(source.Items[i]);
答案 1 :(得分:2)
问题是新创建的Caption
的{{1}}(或任何其他有趣的属性)尚未设置。 VCL提供这个TListItem
参数有点神秘,因为我已经尝试了所有可以想象的添加新列表项的方法,但是没有它们会产生任何有用的Item
参数。在设置属性之前,事件始终被称为。也许你只应该设置这个参数的属性,而不是读取它们。
我认为你必须重新考虑这个设计。可能适用于您的解决方法是使用Item
事件。当然,这不仅会在首次插入项目时触发,也会在项目更改时随时触发。
OnChange
这可能有点像'黑客',但是如果你真的想模仿原始方法有效的方案(也就是说,如果procedure TForm1.DestinationChange(Sender: TObject; Item: TListItem;
Change: TItemChange);
begin
ShowMessage(Item.Caption);
end;
参数已经完全初始化的话),你可以做类似
Item
但如果我是你,我肯定会重新设计。黑客不好。 (至少我不相信这个黑客。)毕竟,你是谁将新项目添加到var
tmpItem: TListItem = nil; // preferably this should
// be a private member of the form class instead
procedure TForm1.DestinationChange(Sender: TObject; Item: TListItem;
Change: TItemChange);
begin
if Assigned(Item) and (Item = tmpItem) then
begin
// Here you got the real item you just added
ShowMessage(Item.Caption);
tmpItem := nil;
end;
end;
procedure TForm1.DestinationInsert(Sender: TObject; Item: TListItem);
begin
tmpItem := Item;
end;
,那你为什么要问Destination
''提醒'你什么时候添加项目?的确,你在这里做到了:
TListView
在此处您将Destination.Items.Add.Assign(source.Items[i]);
列表项添加到source.Items[i]
[严格来说,您在Destination
中创建了一个新项目,然后为其“分配”了Destination
的属性。你可以在source.Items[i]
做任何事情,你也可以在这里做,在这里你可以完全访问有问题的列表项:它只是OnInsert
。用这些数据做你喜欢的事情!