转载

WinForm ListView虚拟模式加载数据 提高加载速度

将VirtualMode 属性设置为 true 会将 ListView 置于虚拟模式。控件不再使用Collection.Add()这种方式来添加数据,取而代之的是使用RetrieveVirtualItem(Occurs when the ListView is in virtual mode and requires a ListViewItem .)和CacheVirtualItems两个事件,单独使用RetrieveVirtualItem也可以,CacheVirtualItems这个事件主要是为了方便编程人员操作缓冲集合,其参数CacheVirtualItemsEventArgs有StartIndex和EndIndex两个属性在虚拟模式下。

在虚拟模式下,从缓冲之中获取所需的数据进行加载,性能会有很大提高。 在其他情况下,可能需要经常重新计算 ListViewItem 对象的值,对整个集合进行此操作将产生不可接受的性能。

示例代码:

 1 using System;  2 using System.Collections.Generic;  3 using System.Windows.Forms;  4   5 namespace WinFormTest  6 {  7     public partial class Form1 : Form  8     {  9         private List<ListViewItem> myCache; 10         public Form1() 11         { 12             InitializeComponent(); 13  14             myCache = new List<ListViewItem>(); 15         } 16  17         private void Form1_Load(object sender, EventArgs e) 18         { 19             listView1.View = View.Details; 20             listView1.VirtualMode = true; 21  22             listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem); 23  24         } 25  26         void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) 27         { 28             if (myCache != null ) 29             { 30                 e.Item = myCache[e.ItemIndex]; 31             } 32             else 33             { 34                 //A cache miss, so create a new ListViewItem and pass it back. 35                 int x = e.ItemIndex * e.ItemIndex; 36                 e.Item = new ListViewItem(x.ToString()); 37             } 38         } 39          40         private void button1_Click(object sender, EventArgs e) 41         { 42             List<Student> list = GetStudentList(); 43             foreach (var item in list) 44             { 45                 ListViewItem listViewItem = new ListViewItem(); 46                 listViewItem.SubItems[0].Text = item.Name; 47                 listViewItem.SubItems.Add(item.Sex); 48                 myCache.Add(listViewItem); 49             } 50             listView1.VirtualListSize = myCache.Count; 51         } 52  53         private List<Student> GetStudentList() 54         { 55             List<Student> list = new List<Student>(); 56             for (int i = 0; i < 2000; i++) 57             { 58                 Student stu = new Student { Name = "student" + i, Sex = "" }; 59                 list.Add(stu); 60             } 61             return list; 62         } 63  64  65         private void button2_Click(object sender, EventArgs e) 66         { 67   68             ListViewItem listItem = new ListViewItem(); 69             listItem.SubItems[0].Text = ""; 70             listItem.SubItems.Add("哈哈"); 71             myCache.Add(listItem); 72             listView1.VirtualListSize = myCache.Count; 73             listView1.Invalidate(); 74         } 75  76     } 77  78     public class Student 79     { 80         public string Sex { get; set; } 81         public string Name { get; set; } 82     } 83 }

总结

(1)必须设置VirtualMode为true并设置VirtualListSize大小

(2)绑定该事件RetrieveVirtualItem

( 3)如果中间更新了数据需要重新设置VirtualListSize,并调用Invalidate()方法

(4)禁用selectedItem,在该模式下使用selectedItem将产生异常,可以用下面方法代替

private List<ListViewItem> FindSelectedAll() {  List<ListViewItem> r = new List<ListViewItem>();  foreach (int item in listView1.SelectedIndices)  {    r.Add(bufferItems[item]);   }   return r;  }  
正文到此结束
Loading...