免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
Board logo

標題: Listview間複製資料項目 [打印本頁]

作者: mhfo    時間: 2013-12-16 08:21     標題: Listview間複製資料項目

原本是考量程式碼的精簡和複製效率,所以才想用addrange來複製
根據您的解答,目前在下是用迴圈再配合BeginUpdate() EndUpdate()來實作
不過效能實在有限,資料筆數過大是關鍵吧(1萬多筆*with 6 subitems)

addrange本身好像也會自動使用上面的函數,不過效能就是比一筆筆add佳
BTW,奮戰的過程中,在網路上在找到一篇將Listviews中資料直接存檔的技巧
效率倒是另人蠻訝異的

     Dim BinFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()

     Dim FS As New System.IO.FileStream("c:\savedlist.txt", IO.FileMode.Create)
     BinFormatter.Serialize(FS, New ArrayList(ListView6.Items))
     FS.Close()

     'Read it back in

     FS = New System.IO.FileStream("c:\savedlist.txt", IO.FileMode.Open)
     ListView5.Items.AddRange(BinFormatter.Deserialize(FS).ToArray(GetType(ListViewItem)))
     FS.Close()

目前嘗試使用memorystream替代System.IO.FileStream中...

---------------------------------------------------------------

對啊你說的沒錯,ListView 在加入大量的物件時的確蠻慢的,不過我也找了一下資料。主要原因應該是預設 ListView 每加一個物件就排序一次,所以有物件數量超過某個程度時會越來越慢。
你可以嘗試讓它不要排序,效能應該會好些:

     ListView2.ListViewItemSorter = Nothing
     ListView2.BeginUpdate()
     For Each item As ListViewItem In ListView1.Items
     ListView2.Items.Add(item.Clone())
     Next
     ListView2.EndUpdate()

而且你找到的沒錯,用序列化再叫 AddRange() 效能也好很多,大概是因為 AddRange() 函式是直接去存取背後的 Win32 ListView 控制項,下面是你上面提到的範例用 MemoryStream 實作:

     Dim BinFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
     Dim mem As New System.IO.MemoryStream()
     BinFormatter.Serialize(mem, New ArrayList(ListView1.Items))

     'Read it back in
     mem.Seek(0, IO.SeekOrigin.Begin)
     ListView2.Items.AddRange(BinFormatter.Deserialize(mem).ToArray(GetType(ListViewItem)))

     mem.Close()
     mem = Nothing


  


上述程式碼運作沒問題,感謝您.
另外也發現了一個有趣現象,就是利用serialize+addrange()並不會將items().tag屬性值一併copy過去,用迴圈+items().clone方式自然沒問題,算是個意外插曲
不過總而言之基本問題順利解決了,未來有機會再來試試Listview的virtual mode,看看能不能根本解決大量資料的執行效能問題,最後再次感謝您的熱心解答^^




歡迎光臨 魚骨頭的雲端圖書館 (http://mhfo.hotbbs.info/) Powered by Discuz! 7.0.0