zoukankan      html  css  js  c++  java
  • Winform ListView虚拟模式

    一、前言

    虚拟模式在许多情况下都很有用。 如果必须从已存在于内存中的非常大的集合填充一个 ListView 对象,则为每项创建一个 ListViewItem 对象会很浪费。 在虚拟模式下,从缓冲之中获取所需的数据进行加载,性能会有很大提高。 在其他情况下,可能需要经常重新计算 ListViewItem 对象的值,对整个集合进行此操作将产生不可接受的性能。

    如下为虚拟模式的一个应用示例(仿VS2010错误列表),截图如下:

    二、虚拟模式相关注意点

    1、设置一个缓存属性,来保存需要加载的数据:

            protected List<ListViewItem> CurrentCacheItemsSource 
            {
                get;
                private set;
            }

    2、通过虚拟模式来加载数据,如下:  

            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.VirtualListSize 
    = items.Count;
                listView.VirtualMode 
    = true;
                listView.RetrieveVirtualItem 
    += new RetrieveVirtualItemEventHandler(listView_RetrieveVirtualItem);

                stripStatusInfo.Text 
    = "当前总共记录数为:" + items.Count;          
            }

    listView.VirtualMode = true;//设置虚拟模式

    listView.VirtualListSize = items.Count;//设置虚拟列表容量大小

    listView.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView_RetrieveVirtualItem);//绑定虚拟操作

     

     

    3、在RetrieveVirtualItem方法中加载相关的数据:

           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 ;
                }
            }

    需要注意及时释放掉所需要的缓存数据,如下:

    if (e.ItemIndex == this.CurrentCacheItemsSource.Count)
    {
        
    this.CurrentCacheItemsSource = null ;
    }

    当e.ItemIndex 的值与缓存中的集合大小相等时,设置缓存为NULL(对象根引用设置为NULL,内存中的对象不再有根引用,所需的内存将由GC第二次回收时释放,相关内容请查看CLR GC)。

     

    三、总结

    当数据为几万条记录时,加载ListView速度非常快,不会造成任何影响,页面显示正常。目前,测试30W条简单的记录,性能还是可以接受的。当然,对于大数据量而言(50W条记录以上),分页才是最佳方式。其次,需要注意的是,对缓存数据需要及时清空,避免不必要的性能损失。

     

    源代码下载:ListView虚拟模式源码

     

  • 相关阅读:
    二叉树中和为某一值的路径
    二叉搜索树的后序遍历序列(important!)
    从上往下打印二叉树
    最小的k个数(important!)
    扑克牌顺子
    栈的压入、弹出序列(important!)
    和为s的连续正数序列(important!)
    数组中只出现一次的数字
    fgets()函数以及fputs()函数
    C语言中的指针
  • 原文地址:https://www.cnblogs.com/jasenkin/p/listview_virtual_model.html
Copyright © 2011-2022 走看看