2008-09-23 64 views
8

我有一個用C#編寫的遺留應用程序,它顯示了一個非常複雜的樹狀視圖,包含10到20萬個元素。C中的慢樹視圖#

在過去,我遇到了一個類似的問題(但在C++中),我用Win32 API提供的OWNERDATA功能解決了這個問題。

C#中是否有類似的機制?

編輯:該計劃是優化創建時間以及瀏覽時間。通過Win32 API可用的方法在這兩種情況下都非常出色,因爲它將初始化時間減少到無,並且元素的請求數量僅限於任何時候可見的元素數量。 Joshl:我們實際上正在按照你的建議做,但我們仍然需要更高的效率。

回答

6

雖然.NET的DataGridView支持這種類型的模型(請參閱DataGridView的VirtualMode屬性),但我不相信.NET TreeView支持您想要的內容。 TreeView會讓你繪製自己的節點,但它不會讓你從一些虛擬商店中填充它們。

如果可能,您可能需要考慮爲您的應用程序使用DataGridView。如果沒有,那麼手動管理節點(如上面的joshl提到的)可能會起作用,如果您可以解決一些問題,那麼在擴展節點時正確刷新屏幕。除此之外,您可能想要查看一些第三方供應商,如this one (Divelements SandGrid),這可能會(強調可能)支持您所需的操作模式。

注:SandGrid不Divelements支持截至7月底的2013

19

提高性能的一種技術是在用戶擴展樹視圖時加載TreeNodes。通常情況下,用戶不需要同時在屏幕上打開20,000個節點。只需加載用戶需要查看的級別以及需要向用戶正確顯示可供選擇的任何子級信息(如果存在子項,擴展圖標等,則展開圖標)。隨着用戶擴展節點,及時加載孩子。

來自Keith的有用提示:使用winforms TreeView,您至少需要一個子節點,否則它不會顯示擴展[+],但是您接着處理TreeNodeExpanded事件以刪除該虛擬節點並填充子節點。

+1

延遲加載...我相信這被稱爲。很好的答案。 – Gishu 2008-09-23 14:23:36

+0

這個答案顯然很好,它已經在我身邊執行了。 – 2008-09-23 14:27:53

4

有使TreeView控件進行更好的一個方法,那就是創建所有子節點和鉤在一起然後將節點添加到TreeView。如果這是我們正在談論的圖形性能。

TreeView tree = new TreeView(); 
TreeNode root = new TreeNode("Root"); 
PopulateRootNode(root); // Get all your data 
tree.Nodes.Add(root); 

否則,通過使用OnTreeNodeExpanded節點加載它們節點。

7

注:此答案由提問者說,他已經做這種事情的編輯無效,但我還是決定由其他人對這個話題

當我搜索仍然張貼以供將來參考我過去做過類似的事情,我傾向於選擇天真的懶惰加載樣式。

  • 使用TreeNode.Tag屬性來保存,你可以用它來查找孩子
  • 使用TreeView.BeforeExpand事件來填充子節點
  • 可以選擇使用TreeView.AfterCollapse事件刪除它們的引用。
  • 爲了讓[+]/[ - ]框出現,我發現的最好方法是創建一個單身虛擬假人TreeNode,它作爲一個孩子添加到所有未填充的節點,並且在填充之前檢查它的存在與BeforeExpand
1

對於Windows C#編程中的大數據,無論是在WPF還是WinForms中,我都會動態地添加節點。我加載最初的樹根+兒童+孫輩。當任何節點展開時,我加載代表擴展節點的孫子的樹節點(如果有的話)。

該模式也適用於數據檢索。如果您確實從數千或數百萬條記錄的數據源加載數據,則可能不希望先加載這些數據。沒有用戶希望等待加載,並且沒有理由加載可能永遠不會被查看的數據。

我通常在後臺線程上根據需要加載孫子或孫輩子節點數據,然後將這些數據封送回UI線程並創建並添加節點。這使UI響應。您可以在視覺上裝飾樹節點以指示它們仍在加載,以便用戶在您的IO之前到達數據存儲。

8

在我們的主要WinForm的應用程序,我們有一個TreeView加載都在同一個鏡頭:

  • 的BeginUpdate()
  • 負載20.000節點
  • EndUpdate()

到目前爲止表現還是不錯的。它實際上是我們沒有用第三方替代的少數幾個組件之一。

根據我的經驗,當您在不調用Begin/EndUpdate()的情況下加載節點(一次性或按需)時,TreeView性能變慢,特別是如果您的節點已排序,但如果調用Begin/EndUpdate )正確,你不應該真的得到與組件本身相關的性能問題。