2010-11-20 137 views
8

在delphi中有幾個字段的列表視圖。線程檢查項目並將其添加到列表視圖。如果有相同的標題,則會在此標題的子項目中添加一個整數。當物品數量少於2000時,表現OK。當檢查和添加項目和項目數大於2000時,性能很差。當物品數量大於20,000時,表現可以描述爲非常緩慢。當項目可能達到50,000或100,000時,有什麼方法可以快速讀取和寫入列表視圖?如何在delphi中快速讀寫listview?

非常感謝你提前

編輯:

我們已經閱讀所有的答案,並感謝大家的幫助。

回答

9

你只需要在「虛擬」模式下使用你的列表。

  1. 將TListBox放在窗體上;
  2. 將Style屬性設置爲lbVirtual。
  3. 將Count屬性設置爲您列表中的項目數。
  4. 然後使用昂達處理程序來提供該文本將被顯示在請求:

如該代碼(與從數據庫或某些數據替換的TStringList或例如):

procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer; 
    var Data: String); 
begin 
    Data := Format('Item %d',[Index+1]); // set the text to be displayed 
end; 

您可以使用lbVirtualOwnerDraw樣式進一步自定義繪圖,並且必須使用OnDrawItem事件處理程序繪製項目。 Delphi文檔中有一些示例代碼(至少在Delphi 7中)。 ;)

在虛擬模式下,可以顯示瞬時方式50000個,還是10,000項。

爲了存儲文本,使用舊的TStringList將比TListBox的Items方法更快,因爲這個Items []屬性必須與每個項目的「慢」GDI消息進行通信,而TStringList只會將文本存儲在Delphi堆中,而這通常要快得多。

+0

非常感謝。 – Dylan 2010-11-23 04:12:03

6

您可以通過在列表視圖上調用BeginUpdate和EndUpdate來提高性能,方法是在更新時防止ListView重繪本身。但這可能不會給你提供你想要的。 此外,您需要知道直接從一個線程訪問VCL控件是不安全的,除非同步。

我認爲最好是跳過列表視圖並選擇第三方控件,如Virtual Tree View,它既好又免費。 :)

+0

我很快查看了虛擬樹視圖組件。在應用程序中使用多個標準TListView和TTreeView控制器插入到位並插入代碼中的列和樹節點時,它有多「難」?我們是否正在談論這些部分的完整重寫?如果是這樣,只要堅持TTreeView和TListView bu改變他們作爲虛擬工作,速度增益會有多大的差異? – inquam 2013-01-11 12:32:03

+0

我真的不知道速度差異。我認爲虛擬TListView也可能相當快,但我沒有那樣使用它,所以我不能給你一個適當的比較。 – GolezTrol 2013-01-11 14:28:42

10

Delphi TListView控件是Windows列表視圖組件的包裝。在其默認操作模式下,列表數據的副本將從您的應用程序傳輸到Windows控件,並且速度很慢。

這種替代方法在Windows術語中稱爲虛擬列表視圖。您的應用不會將數據傳遞給Windows控件。相反,當控件需要顯示數據時,它只會向您的應用程序請求所需的數據。

Delphi TListView控件通過使用OwnerData屬性公開虛擬列表視圖。你必須重新編寫你的列表視圖代碼,但它確實是唯一的解決方案。

+2

我也會建議他不得不切換到列表視圖的虛擬模式。我們個人使用Golztrol提到的虛擬TreeView。 – 2010-11-20 12:32:53

+1

Mike Lischke的虛擬樹視圖非常棒。如果你有一個列表而不是一棵樹,那麼使用列表視圖組件有很多需要說的,因爲它允許你爲平臺使用本地組件。而且,虛擬樹視圖呈現出相當的學習曲線。 – 2010-11-20 12:37:39

+1

不幸的是在這種模式下列表視圖不支持GroupView ... – Tupel 2014-12-03 09:45:21

2

嘗試使用OnData處理程序的虛擬Listview。

數據保留在您自己的數據結構中,listview會調用您的OnData處理函數以獲取它需要的數據項。即您在請求時從數據結構中提取特定數據。

你的其他工作是保持列表視圖的ItemCount爲列表中的項目數。

3

幾年前,我們發現除了BeginUpdate/EndUpdate之外,在向其添加大量數據之前將ListView的ViewStyle更改爲vsIcon,並在我們完成大幅改進的性能之後返回到vsRepord。如果我沒有記錯,那是在Windows 98和Windows 2000上,所以我不確定這是否仍然如此。

3

更新項目時,BeginUpdate和EndUpdate是絕對必須的。 從您的描述中,它聽起來像循環查找特定標題的項目。這很慢,並且在數據量更大的情況下會更明顯。

既然您在尋找匹配的標題,請使用列表視圖FindCaption函數。

這個窗口調用搜索項目,相當快速和簡單。如果它發現它將回傳項目,並且您可以引用它來更新子項目。否則,創建一個新項目並繼續處理。

只要你的線程安全,你應該能夠看到體面的表現。

HTH。

+0

FindCaption IIRC導致API調用,但我可能是錯誤的。我沒有德爾福在這臺機器上100%確定。 – 2010-11-21 03:11:13