你的位置:首页 > ASP.net教程

[ASP.net教程]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       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; }