Back in February a fellow Vertigo employee, Alan, blogged about “WPF: How to filter ListBox items on the fly”, which got me thinking about how could I do the same thing with LINQ.
Additionally, as I rarely have the luxury to be working with ObjectDataProviders, SqlDataProviders, DataSets, and such, a solution that worked with collections of Business Objects, which typically don’t have a “Filter” method, would be very useful.
LINQ + Collections.Generic
So with LINQ working with the generic collections, implementing a filter becomes very easy.
In the below code I filter a List<> of NameEntry objects for ListBox(lstNames) based on the value entered into a TextBox(txtFilter). NameEntry has several properties, but we’re only interested in Name for now.
List<NameEntry> nameList = NameEntry.GetTestDataList();
var filteredList = from item in nameList
where item.Name.ToLower().Contains(txtFilter.Text.ToLowerInvariant())
select item;
lstNames.DataSource = filteredList;
lstNames.DataValueField = "Name";
lstNames.DataBind();
The highlighted code is all you need to accomplish this simple filter.
Alternatively, you could replace the entire LINQ statement with a call to an extension method that LINQ adds to Generic Collections called Where<>(), like so:
var filteredList = nameList.Where(item =>
item.Name.ToLowerInvariant().Contains(txtFilter.Text));
Which has even fewer characters of code; although for those unaccustomed to lambdas it can be harder to read.
3/24/08 - Corrected sample to use ToLowerInvariant()