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 对象的值,对整个集合进行此操作将产生不可接受的性能。

示例代码:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace WinFormTest
{
    public partial class Form1 : Form
    {
        private List<ListViewItem> myCache;
        public Form1()
        {
            InitializeComponent();
            myCache = new List<ListViewItem>();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            listView1.View = View.Details;
            listView1.VirtualMode = true;
            listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
        }
        void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            if (myCache != null )
            {
                e.Item = myCache[e.ItemIndex];
            }
            else
            {
                //A cache miss, so create a new ListViewItem and pass it back.
                int x = e.ItemIndex * e.ItemIndex;
                e.Item = new ListViewItem(x.ToString());
            }
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            List<Student> list = GetStudentList();
            foreach (var item in list)
            {
                ListViewItem listViewItem = new ListViewItem();
                listViewItem.SubItems[0].Text = item.Name;
                listViewItem.SubItems.Add(item.Sex);
                myCache.Add(listViewItem);
            }
            listView1.VirtualListSize = myCache.Count;
        }
        private List<Student> GetStudentList()
        {
            List<Student> list = new List<Student>();
            for (int i = 0; i < 2000; i++)
            {
                Student stu = new Student { Name = "student" + i, Sex = "男" };
                list.Add(stu);
            }
            return list;
        }
        private void button2_Click(object sender, EventArgs e)
        {
 
            ListViewItem listItem = new ListViewItem();
            listItem.SubItems[0].Text = "女";
            listItem.SubItems.Add("哈哈");
            myCache.Add(listItem);
            listView1.VirtualListSize = myCache.Count;
            listView1.Invalidate();
        }
    }
    public class Student
    {
        public string Sex { get; set; }
        public string Name { get; set; }
    }
}

总结

  (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不分页加载大量数据

WinForm的ListView在加载大量数据时会出现闪烁的问题,同时数据加载很慢。如果你的列表中有超过千条的数据且不做特殊处理还是用普通的ListView.Items.Add(),估计你的用户得抱怨了。

下面说下解决方法:

1、使用listView1.Items.AddRange()代替Add

这种方法需要先将数据放入一个缓存数组中,然后调用AddRange一次性加入ListView中,同时可以用一个计数器记录一次性加入缓存的数量,如下:

             listView1.Items.Clear();
            if (vList.Count > 0)
            {
                
                int indexI = 0;
                List<ListViewItem> listBuffer = new List<ListViewItem>();
                foreach (var item in vList)
                {
                    ListViewItem li = new ListViewItem();
                    li.ImageIndex = 0;
                    li.SubItems[0].Text = item.Name;
                    li.Tag = item;
                    li.ForeColor = item.Status == 0 ? Color.Green : Color.Red;
                    listBuffer.Add(li);
                    
                    if (indexI++ % 1000 == 0)
                    {
                        listView1.Items.AddRange(listBuffer.ToArray());
                        listBuffer.Clear();
                    }
                    if (indexI % 50 == 0)
                    {
                        Application.DoEvents();
                    }
                }
                listView1.Items.AddRange(listBuffer.ToArray());

            }

这样可以减少ListView闪烁的次数,数据量不是很大时有效果。

2、自定义ListView类

下面这个类在网上广为流传,虽然解决了ListView闪烁的问题,但是在打开速度上和原来没什么区别,同时带来一个问题就是如果程序切换到别的ListView上,数据还会继续忘原来的ListView中添加,直到数据全面添加完成。

    public class ListViewLargeData : System.Windows.Forms.ListView
    {
        public ListViewLargeData()
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.EnableNotifyMessage, true);
        }
        protected override void OnNotifyMessage(Message m)
        {
            if (m.Msg != 0x14)
            {
                base.OnNotifyMessage(m);
            }
        }
    }

3、开启ListView的VirtualMode模式

  此方式也是本文重点推荐的方式,可以实现不闪烁效果,而且打开速度很快。往往好的效果带来的问题是代码较为复杂,具体写法可以看官方示例http://msdn.microsoft.com/zh-cn/library/system.windows.forms.listview.virtualmode.aspx,下面说下需要注意的几点:

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

            listView1.VirtualMode = true;
            listView1.VirtualListSize = bufferItems.Count;
            listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView_RetrieveVirtualItem);

    (2)绑定该事件为ListView计算Item

        void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            e.Item = m_hListViewItems[e.ItemIndex];
        }

    (3)如果中间更新了数据需要重新设置VirtualListSize,并调用Invalidate()方法(此方法并非必须请高手指点)。

            listView1.VirtualListSize = bufferItems.Count;
            listView1.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;
        }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, new
, 事件
模式
winform listview、c winform listview、winform listview样式、winform listview美化、winform listview分组,以便于您获取更多的相关知识。

时间: 2024-12-23 19:28:52

WinForm ListView 大数据提高加载速度的方法 虚拟模式加载的相关文章

周昆平:大数据提高银行风险控制能力

随着大数据技术的发展,银行获取此类信息的成本极小,数据收集的维度.广度和时点得到了扩展,可对客户的交易信息和行为轨迹进行实时的监测,此时得到的结果因依靠庞大数据的支撑,其质量和可信度大大增强. 周昆平:大数据提高银行风险控制能力 周昆平:大数据提高银行风险控制能力 伴随着互联网和大数据的快速发展,互联网和传统行业的融合开始加速,在互联网浪潮下,传统行业重新找到了发展的新方向.互联网与传统银行业可以融合发展,即形成新型的"互联网+"模式,该模式的本质在于将互联网技术(大数据处理.云计算)

陈敏尔在贵州高院调研时强调 运用司改和大数据提高司法效率

6月20日,贵州省委书记.省人大常委会主任陈敏尔到贵州省高级人民法院调研司法改革工作.他强调,全省法院系统要深入学习贯彻习近平总书记重要讲话精神,把执法为民作为第一追求,把司法体制改革和大数据应用作为"车之两轮",把服务大局作为重要任务,把队伍建设作为根本保证,大力提高司法效率,切实维护社会公平正义. 陈敏尔考察了贵州高院科技法庭和立案一庭,听取了贵州高院大数据工作汇报,参观了执行指挥中心和12368诉讼服务平台.陈敏尔边走边看,亲切看望慰问法院工作人员,对贵州高院运用大数据提高审判效

河南濮阳:运用大数据提高发现涉农问题准确度

今年2月底至4月中旬,河南省濮阳市委3个巡察组对市委农办.市农业畜牧局.市林业局.市水利局.市农机局.市扶贫办进行了常规巡察,县区20个巡察组围绕项目和资金,对相应的县区直单位进行了专项巡察.本轮巡察共向县(区)移交问题线索342件,截至6月30日,已办结145件,党政纪处分56人,组织处理1人,其他处理39人,移送司法机关4人. 聚焦涉农领域 瞄准基层腐败重灾区 巡察组有针对性地向财政.审计等相关部门进行函询,对近年来的涉农项目和资金进行整体了解.要求各被巡察单位纪检派驻机构将本单位的廉政风险

运用大数据提高政协协商能力

在"创新社会治理体制"的时代背景下,笔者认为可以切实运用大数据,提高政协协商能力. 运用大数据提高政协协商能力的意义.运用大数据了解社情民意,使政协工作更加精准.移动互联网与自媒体的兴起给每一个公民向社会发表见解和意见的机会,大数据改变了人们长期以来依靠经验.习惯进行工作的方式,使直觉判断让位于精准的数据分析.只要掌握足够数据,就能及时精准地了解民情民意,从而有针对性地提出议案和建议.通过大数据技术的数据获取,既可以了解当前情况,又可以追踪较长时间段社情民意的信息动态,为政协工作提供依

大数据提高创意产品转化率 挖掘推动文化消费

2013年即将收尾,有太多关于"大数据"的讨论.且不去说"前大数据时代"和"后大数据时代"的差异,信息时代的日新月异已然给文化创意产业带来新的机遇和挑战."大数据商业应用第一人"--因<大数据时代>走红的牛津大学互联罿/a>研究院教授维克托·迈尔·舍恩伯格表示,大数据也存在"短板",大数据来源于现实,基于过去的数据可以预测经济.防灾避险.预防犯罪,而人类的许多想法来源于脑海,甚至会产生许多

用innerhtml提高页面打开速度的方法

这篇文章介绍了用innerhtml提高页面打开速度的方法,有需要的朋友可以参考一下   查看源代码,可以发现,页首的登陆代码位置,只有一行 复制代码 代码如下: <div id="headtop"></div> 而flash幻灯的位置,也只有一行 复制代码 代码如下: <div id="index_slide"></div> 对于这种需要耗时的代码,最好是放在页面最后面加载,然后用innerhtml的方法加载到对应位置

大数据将如何重构汽车产业的商业模式?

没有整合和挖掘的数据,价值也呈现不出来.海量数据的产生.获取.挖掘及整合,使之展现出巨大的商业价值,这就是公子义理解的大数据.在互联网对一切重构的今天,这些问题都不是问题.那么大数据将如何重构商业模式呢? 一.大数据将如何重构汽车行业的商业模式? 在人的一生中,汽车是一项巨大的投资.以一部30万车.7年换车周期来算,每年折旧费4万多(这里还不算资金成本),加上停车.保险.油.维修.保养等各项费用,每年耗费应在6万左右.汽车产业也是一个很长产业链的龙头产业,这个方面只有房地产可以媲美. 但同时,汽

如何利用数据赚钱?大数据价值变现的10种商业0模式及利弊分析

有人说大数据是「石油」是「黄金」,涂子沛说大数据是「土壤」,而马云说大数据是「生产资料」,我觉得他们说得都对,但是也都不对. 因为大数据就是「大数据」. 当大数据应用在不同的领域和不同的场景下,所产生的意义及其所代表的意义也都不一样,你没有办法用一句话完全概况.大数据是互联网时代不可或缺的产物,不管你愿不愿意,大数据就在那里,你我都是大数据的制造者同时也是受惠者,这个生态圈的闭环已经形成,而且还在不断的延伸到各行各业,为不同的行业创造着更新.更大的价值. 2015年9月,我曾经写过一篇名叫<一文

基于大数据应用探索“互联网+卷烟市场监管”新模式

"互联网+卷烟市场监管"新模式构建思路 卷烟市场监管四级预警处理机制 随着大数据和互联网快速发展,如何通过大数据的应用,创新卷烟市场监管模式已成为现阶段烟草专卖部门亟待解决的问题.笔者认为,应基于大数据的应用,设计"互联网+卷烟市场监管"新模式,以数据采集为基础,通过打造四个平台,构建四个模块,实现专卖管理转型提升. 强化数据采集 高质量的数据库是运用大数据的基础,而大数据的运用也为提升数据质量创造了更大的空间.烟草专卖部门只有拥有真实.准确.完备的卷烟市场监管数据