原本是考量程式碼的精簡和複製效率,所以才想用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,看看能不能根本解決大量資料的執行效能問題,最後再次感謝您的熱心解答^^ |