在虚拟模式下,ListView控件不需要托管任何数据,它只需要知道有多少行/线。当控制能够显示的可见行滚动到视图中时,需要提供一个回调方法来传递数据以供显示。例如,能够显示大约1亿行,并将行号作为文本(德语)表示。
背景
这个简单的原型是在开始创建TreeListView作为ListView的扩展之前创建的,TreeListView也在虚拟模式下运行,可以在CodeProject上找到:VirtualModeTreeListView。
使用代码
为了使ListView在虚拟模式下运行,需要将适当的属性"VirtualMode"设置为true。一旦在某个表单上放置了WindowsForms ListView控件,ListView的属性窗口就会出现。确保ListView对象被选中。
激活虚拟模式后,还必须订阅"RetrieveVirtualItem"事件,因为控件会收集关于可见/在视图中的行的数据。如果忘记订阅这个事件,控件会抛出一个异常。所以要满足要求。
现在,需要在事件"RetrieveVirtualItem"的回调处理程序中提供一些代码。当行可见时,控件会收集数据以在控件的列中显示数据。因此,控件期望一个普通的ListViewItem对象,由任何附加的ListViewSubItem对象作为子对象组成,这取决于控件配置的列。请记住,如果不使用虚拟模式,将不得不用这样的对象填充控件,以便控件能够在每行的列中查看数据。否则,控件将是"空"的。
这个例子只是取回调方法"RetrieveVirtualItem"传入的行号,并MakeText()创建行号的文本表示。
private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
ListViewItem lvi = new ListViewItem();
// 创建一个listviewitem对象
lvi.Text = nt.MakeText(e.ItemIndex);
// 将文本分配给项目
ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem();
// 子项目
NumberFormatInfo nfi = new CultureInfo("de-DE").NumberFormat;
nfi.NumberDecimalDigits = 0;
lvsi.Text = e.ItemIndex.ToString("n", nfi);
// 子项目文本
lvi.SubItems.Add(lvsi);
// 将子项目分配给项目
e.Item = lvi;
// 将项目分配给事件参数的项目属性
}
MakeText()方法只是为某个数字创建适当的字符串,但文本是德语。有一个名为NumberText的类,用于创建字符串。请参阅源文件NumberText.cs了解详细信息。
仍然需要做的一件事是告诉ListView它有多少行/线。在Form的Load事件中这样做:
private void Form1_Load(object sender, EventArgs e)
{
listView1.VirtualMode = true;
// 开启虚拟模式
listView1.VirtualListSize = 1000000000;
// 给它1百万行
}
可能会对在虚拟模式下运行的treelistview感兴趣:VirtualModeTreeListView。