Delphi Listview onInsert问题

时间:2011-06-06 22:42:32

标签: delphi listview

我正在使用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;

由于

科林

2 个答案:

答案 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。用这些数据做你喜欢的事情!