将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[].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 = ; i < ; 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[].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; }
}
}

子线程+虚拟模式操作listview

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private List<ListViewItem> myCache;
private delegate void DispMSGDelegate(int index, string MSG); public Form1()
{
InitializeComponent();
this.listView1.Columns.Add("编号", , HorizontalAlignment.Right);
this.listView1.Columns.Add("姓名", , HorizontalAlignment.Right);
myCache = new List<ListViewItem>(); } private void button1_Click(object sender, EventArgs e)
{
progressBar1.Maximum = ;
Thread tWorkingThread = new Thread(Thread_DisplayMSG);
//ChaosThreadList.Add(tWorkingThread);
tWorkingThread.Start(); }
private void Thread_DisplayMSG()
{
List<Student> list = GetStudentList();
int k = ;
foreach (var item in list)
{
progressBar1.Value = k;
k++; DispMsg(k, item.Name);
}
listView1.VirtualListSize = myCache.Count;
} private void DispMsg(int iIndex, string strMsg)
{
if (this.listView1.InvokeRequired == false) //如果调用该函数的线程和控件lstMain位于同一个线程内
{
ListViewItem listViewItem = new ListViewItem();
listViewItem.SubItems[].Text = iIndex.ToString();
listViewItem.SubItems.Add(strMsg);
myCache.Add(listViewItem);
}
else //如果调用该函数的线程和控件lstMain不在同一个线程
{
//通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作
DispMSGDelegate DMSGD = new DispMSGDelegate(DispMsg); //使用控件lstMain的Invoke方法执行DMSGD代理(其类型是DispMSGDelegate)
this.listView1.Invoke(DMSGD, iIndex, strMsg); }
} private List<Student> GetStudentList()
{
List<Student> list = new List<Student>();
for (int i = ; i < ; i++)
{
Student stu = new Student { Name = "student" + i, Sex = "男" };
list.Add(stu);
}
return list;
}
private 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 Form1_Load(object sender, EventArgs e)
{
listView1.View = View.Details;
listView1.VirtualMode = true; listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
} }
public class Student
{
public string Sex { get; set; }
public string Name { get; set; }
}
}

WinForm ListView虚拟模式加载数据 提高加载速度的更多相关文章

  1. 实现虚拟模式的动态数据加载Windows窗体DataGridView控件 .net 4.5 (一)

    实现虚拟模式的即时数据加载Windows窗体DataGridView控件 .net 4.5 原文地址 :http://msdn.microsoft.com/en-us/library/ms171624 ...

  2. [Python]-pandas模块-机器学习Python入门《Python机器学习手册》-02-加载数据:加载文件

    <Python机器学习手册--从数据预处理到深度学习> 这本书类似于工具书或者字典,对于python具体代码的调用和使用场景写的很清楚,感觉虽然是工具书,但是对照着做一遍应该可以对机器学习 ...

  3. [Python]-sklearn模块-机器学习Python入门《Python机器学习手册》-02-加载数据:加载数据集

    <Python机器学习手册--从数据预处理到深度学习> 这本书类似于工具书或者字典,对于python具体代码的调用和使用场景写的很清楚,感觉虽然是工具书,但是对照着做一遍应该可以对机器学习 ...

  4. ListView虚拟模式封装

    public class ListViewAH : ListViewEx { #region 虚拟模式相关操作 ///<summary> /// 前台行集合 ///</summary ...

  5. AJAX删除事件与加载数据

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 微信小程序云开发-列表数据分页加载显示

    一.准备工作 1.创建数据库nums,向数据库中导入108条数据 2.修改数据库表nums的权限 二.新建页面ListPaginated 1.wxml文件 <!-- 显示列表数据 --> ...

  7. Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...

  8. WinForm ListView不分页加载大量数据

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

  9. ListView用法及加载数据时的闪烁问题和加载数据过慢问题

    ListView介绍及添加数据时的闪烁问题 1.     ListView类 1.1 ListView常用的基本属性: (1)FullRowSelect:设置是否行选择模式.(默认为false) 提示 ...

随机推荐

  1. shell脚本--数值计算

    原生bash不支持简单的数学运算,即使是最简单的加减乘除 但是,可以使用$[]和expr来实现整数运算 如果要实现小数运算,可以使用bc命令 使用$[]来实现: #!/bin/bash #文件名:te ...

  2. Kitematic - VirtualBox is not installed. Docker for windows 10

    Kitematic - VirtualBox is not installed. Docker for windows 10 https://github.com/docker/kitematic/i ...

  3. SyntaxHighlighter行号显示错误问题解决方案

    SyntaxHighlighter是根据代码中的换行符分配行号的.但是,如果一行代码或者注释比较长,在页面显示时需要分成多行显示,会出现行号对不上的问题,像这样: 通过设置CSS强制不换行,可以保证行 ...

  4. Oracle18c OnlyExadataVersion 安装说明

    1.根据惜分飞还有盖国强老师云和恩墨的文章, 验证了下OnlyExadataVersion的Oracle18c的数据库安装过程. 2.oracle参数修改以及创建用户, 目录, 修改.bash_pro ...

  5. angular4 组件通讯、生命周期

    主要通讯形式 父组件通过属性绑定到子组件,子组件通过事件传递参数到父组件 父组件通过局部变量获取子组件的引用 父组件使用@ViewChild获取子组件的引用 两个不相关联的组件使用中间人模式交互 终极 ...

  6. Java 死锁

    什么是死锁? 当一个线程永远地持有一个锁,并且其他线程都尝试去获得这个锁时,那么它们将永远被阻塞,当线程A持有锁1想获取锁2,当线程B持有锁2想获取锁1 这种情况下就会产生2个线程一直在阻塞等待其他线 ...

  7. Lodop调整打印项输出顺序 覆盖与层级

    Lodop中的打印项,如果有输出在同一位置,或部分位置重叠的地方,打印项之间是怎么覆盖的呢?在JS里,按照Lodop语句打印项先后的执行顺序,先执行的先输出,后执行的后输出,如果有后面的打印项和前面的 ...

  8. 注册页面手机验证码无跳转接收[html+js+ajax+php]

    [学习笔记] 来源:注册时需要使用短信验证码,但是注册的时候,点击接收验证码时,会产生跳转(尼玛,这不是我想要的啊!o(╥﹏╥)o) 查询资料和看书之后,知道使用js+ajax可以实现,就从网上找了一 ...

  9. mysql format函数对数字类型转化的坑

    原值param = 1234.5678 format(param, 2) (不建议)      结果,字符串类型,123,4.57  会导致你图表char 生成失败,直接变0 convert(para ...

  10. Leetcode 461.汉明距离 By Python

    两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 注意: 0 ≤ x, y < 231. 示例: 输入: x = 1, y ...