2011-06-06 92 views
1

我使用2個列表視圖,並將項目從一個複製到另一個(使用下面的代碼),但是當觸發目標Listview的onInsert事件時,傳遞的Item值始終爲零,而不是新移動的列表項目,有人可以指出我做錯了什麼?Delphi Listview onInsert問題

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

你不是*複製*項目,你*移動*他們。 – 2011-06-06 22:56:14

+0

我以爲我知道答案,但我錯了。我自發的反應是,VCL /共同控制行爲奇怪... – 2011-06-06 23:10:39

+0

+1,因爲這是一個謎! – 2011-06-06 23:22:09

回答

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]); 
+0

如果調試DCU未打開,它看起來像'nil'。 – 2011-06-07 00:05:57

+0

@Andreas - 仍然不能重複,也許版本具體? 2007 here .. – 2011-06-07 00:11:48

+0

2009年,對象檢查員拒絕顯示有關「Item」參數的任何細節,除非調試DCU處於打開狀態。當然,它*不是*'nil',但它看起來像它。 [無調試DCU](http://privat.rejbrand.se/noitem.png)與[調試DCU](http://privat.rejbrand.se/isitem.png) – 2011-06-07 00:13:02

2

的問題是,新創建TListItemCaption(或任何其他有趣的屬性)尚未被設定。 VCL提供這個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中你可以做的任何事情,你可以在這裏做,並在這裏你可以完全訪問有問題的列表項:它只是source.Items[i]。用這些數據做你喜歡的事!

+1

爲最後一部分+1,讓我回滾。 – 2011-06-07 01:47:37

+0

感謝您的幫助,順便說一下我正在使用Delphi 7.不管怎樣,當我嘗試上述我可以訪問item.caption但是我無法訪問任何item.subItems?在我看來,他們目前還沒有被分配? Colin – colin 2011-06-07 08:14:43

+0

@colin:這就是我寫「至少我不會相信這種黑客行爲」的原因。 – 2011-06-07 11:57:19