将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 else33 {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 Student79 {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; }
原标题:WinForm ListView虚拟模式加载数据 提高加载速度
关键词:ie