Here you go - a fully worked example that filters a million records
using different filters, pretty-much instantly.
I hope you'll forgive my using C# 3 here - it makes writing both forms
snippets and delegates so much easier (and this uses both quite a
lot)... but you'll need VS 2008 (Express will do) to see it working.
Marc
using System;
using System.Collections.Generic;
using System.Windows.Forms;
public class Entity
{
public int Value { get; set; }
public int Id { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
// create some dummy data
const int SIZE = 1000000;
List<Entity> list = new List<Entity>(SIZE);
Random rand = new Random();
for (int i = 0; i < SIZE; i++)
{
list.Add(new Entity { Id = i, Value = rand.Next() });
}
Application.EnableVisualStyles();
// create the UI
using(ListView lv = new ListView {
Dock = DockStyle.Fill,
VirtualMode = true,
View = View.Details,
Columns = {"Id", "Value"}})
using(Button bAll = new Button {
Dock = DockStyle.Bottom,
Text = "All"})
using (Button bEvenRows = new Button {
Dock = DockStyle.Bottom,
Text = "Even Rows" })
using (Button bDivValues = new Button {
Dock = DockStyle.Bottom,
Text = "Values div 7" })
using(Form form = new Form {
Text = "Virtual Demo",
Controls = {lv, bAll, bEvenRows, bDivValues}}) {
// create a place-holder for the filtered sublist
List<Entity> filtered = null;
// create a delegate we can use to change the filter
Action<Predicate<Entity>> changeFilter = where => {
filtered = list.FindAll(where);
lv.VirtualListSize = filtered.Count;
lv.Update();
};
// wire the virtual mode data retreival
lv.RetrieveVirtualItem += (o,e) => {
Entity item = filtered[e.ItemIndex];
e.Item = new ListViewItem(
new[] {
new ListViewItem.ListViewSubItem() {Text =
item.Id.ToString()},
new ListViewItem.ListViewSubItem() {Text =
item.Value.ToString()}
}, 0);
};
// wire the buttons to apply different filters
bAll.Click += (o, e) => changeFilter(x => true);
bEvenRows.Click += (o, e) => changeFilter(x => x.Id % 2 ==
0);
bDivValues.Click += (o, e) => changeFilter(x => x.Value %
7 == 0);
// wire the form to display everything initially
form.Load += (o,e) => bAll.PerformClick();
// show the form
Application.Run(form);
}
}
}