當 ListView 需要顯示極大量資料(如數萬筆以上)時,若為每一筆建立 ListViewItem 物件,記憶體與效能開銷極大。虛擬模式 (VirtualMode) 讓控制項僅在需要顯示時從快取取得資料,大幅提升效能。本文以模擬 Visual Studio 2010 錯誤清單為例,示範虛擬模式實作要點。
使用 List<ListViewItem> 做為資料快取來源:
protected List<ListViewItem> CurrentCacheItemsSource { get; private set; }
private void LoadListViewItems(List<ListViewItem> items)
{
listView.Items.Clear();
if (items == null)
{
stripStatusInfo.Text = "當前總共記錄數為:0";
return;
}
listView.GridLines = true;
listView.FullRowSelect = true;
listView.View = View.Details;
listView.Scrollable = true;
listView.MultiSelect = false;
listView.HeaderStyle = ColumnHeaderStyle.Clickable;
listView.Visible = true;
// 關鍵三行:啟用虛擬模式、設定虛擬項目數、綁定取得項目事件
listView.VirtualMode = true;
listView.VirtualListSize = items.Count;
listView.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView_RetrieveVirtualItem);
stripStatusInfo.Text = "當前總共記錄數為:" + items.Count;
CurrentCacheItemsSource = items; // 指派快取
}
此事件在控制項需要顯示特定索引項目時觸發,直接從快取取回對應項目:
void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
if (this.CurrentCacheItemsSource == null || this.CurrentCacheItemsSource.Count == 0) return;
e.Item = this.CurrentCacheItemsSource[e.ItemIndex];
// 釋放快取:當索引等於集合大小時,表示已無需顯示更多項目
if (e.ItemIndex == this.CurrentCacheItemsSource.Count)
{
this.CurrentCacheItemsSource = null; // 移除根引用,交由 GC 回收
}
}
記憶體管理提醒:將快取設為
null可移除根引用,讓 GC 在下一次回收時釋放記憶體,避免長佔記憶體造成效能損耗。
關鍵原則:及時清空快取資料,避免不必要的記憶體佔用。
原始碼下載:ListView 虛擬模式原始碼