using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace ListViewVirtualMode
{
public partial class Form1 : Form
{
private ListViewItem[] lvi;
private ListView listView1;
public Form1()
{
InitializeComponent();
}
void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
e.Item = lvi[e.ItemIndex];
}
void listView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.DrawDefault = true;
if (!e.Item.Checked)
{
e.Item.Checked = true;
e.Item.Checked = false;
}
}
void listView_MouseClick(object sender, MouseEventArgs e)
{
ListView lv = (ListView)sender;
ListViewItem lvi = lv.GetItemAt(e.X, e.Y);
if (lvi != null)
{
if (e.X < (lvi.Bounds.Left + 16))
{
lvi.Checked = !lvi.Checked;
lv.Invalidate(lvi.Bounds);
}
}
}
void listView_MouseDoubleClick(object sender, MouseEventArgs e)
{
ListView lv = (ListView)sender;
ListViewItem lvi = lv.GetItemAt(e.X, e.Y);
if (lvi != null)
lv.Invalidate(lvi.Bounds);
}
void SetupListview(bool blnVirtual)
{
// Get ListView working
this.listView1 = new ListView();
this.listView1.Dock = DockStyle.Fill;
// This is what we want!!
this.listView1.View = View.List;
this.listView1.CheckBoxes = true;
if (blnVirtual)
{
// This makes it real fast!!
this.listView1.RetrieveVirtualItem +=
new RetrieveVirtualItemEventHandler(
listView_RetrieveVirtualItem);
this.listView1.VirtualListSize = lvi.Length;
this.listView1.VirtualMode = true;
// This is what you need, for drawing unchecked checkboxes
this.listView1.OwnerDraw = true;
this.listView1.DrawItem +=
new DrawListViewItemEventHandler(listView_DrawItem);
// Redraw when checked or doubleclicked
this.listView1.MouseClick += new MouseEventHandler(listView_MouseClick);
this.listView1.MouseDoubleClick += new MouseEventHandler(listView_MouseDoubleClick);
}
else
{
// The other way
this.listView1.Items.AddRange(lvi);
}
// Show in main form
this.Controls.Add(this.listView1);
}
private void Test()
{
// You can switch between Virtual and Normal
bool blnVirtual = true;
// Get the ListViewItem cache up and running
int NR = 100000;
lvi = new ListViewItem[NR];
for (int intI = 0; intI < lvi.Length; intI++)
lvi[intI] = new ListViewItem(intI + " test");
// Check some random items, just for testing
lvi[3].Checked = true;
lvi[5].Checked = true;
lvi[12].Checked = true;
lvi[NR-2].Checked = true;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Reset();
stopwatch.Start();
SetupListview(blnVirtual);
stopwatch.Stop();
this.Text = "ListView VirtualMode=" + blnVirtual +
" : "+ lvi.Length + " items in " +
stopwatch.ElapsedMilliseconds + " mS";
}
private void Form1_Load(object sender, EventArgs e)
{
Test();
}
private void button1_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (ListViewItem var in lvi)
{
if (var.Checked)
{
sb.Append(var.Text);
sb.Append("\r\n");
}
}
MessageBox.Show(sb.ToString());
}
}
}
接下来
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace ListViewVirtualMode
{
public partial class Form2 : Form
{
private ListViewItem[] lvi;
public Form2()
{
InitializeComponent();
}
void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
e.Item = lvi[e.ItemIndex];
}
private void Test()
{
int NR = 10000;
lvi = new ListViewItem[NR];
for (int intI = 0; intI < lvi.Length; intI++)
lvi[intI] = new ListViewItem(new string[] { intI + " test1", intI + " test2" });
listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView_RetrieveVirtualItem);
listView1.VirtualListSize = lvi.Length;
listView1.VirtualMode = true;
}
private void Form2_Load(object sender, EventArgs e)
{
Test();
}
//更新
private void button1_Click(object sender, EventArgs e)
{
int NR = 10000;
lvi = new ListViewItem[NR];
for (int intI = 0; intI < lvi.Length; intI++)
lvi[intI] = new ListViewItem(new string[] { intI + " " + DateTime.Now.ToString(), intI + " " + DateTime.Now.ToString() });
listView1.Visible = false;
listView1.Visible = true;
}
}
}