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虚拟模式源码

 

posted @   jasen.kin  阅读(12944)  评论(8编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示