tags:

views:

578

answers:

3

I have an ObservableCollection of about 1000 objects that needs to be filtered (searched) by the end user. The user must be able to search by name or employee id. The List Control consumes FilteredEmployees and Employees is loaded up with everything on page load.

I currently have it set up as such:

public ObservableCollection<EmployeeServicesData> Employees { get; set; }
public ObservableCollection<EmployeeServicesData> FilteredEmployees { get; set; }

internal void FilterEmployee(string searchText, bool isByName)
{
    if (searchText.Length > 0)
    {
        IEnumerabe<EmployeeServicesData> filter;

        if (isByName)
            filter = Employees.Where(x => x.Name.Length >= searchText.Length).Where(x => x.Name.Substring(0, searchText.Length) == searchText.ToUpper());
        else
            filter = Employees.Where(x => x.EmployeeNumber.ToString().Length > searchText.Length).Where(x => x.EmployeeNumber.ToString().Substring(0, searchText.Length) == text);

        foreach (EmployeeServicesData employee in filter)
            FilteredEmployees.Add(employee);
    }
}

Sanitation is handled before this method.

This doesn't smell very efficent. Should I use two methods for this, or is there a better way to handle filtering?

I'd like to keep Employees at an unchanged state so I can repopulate FilteredEmployees to the full list without hitting the DB again.

+1  A: 

It looks like you're trying to see if searchText is contained in the Employee name, or in the Employee Number.

You could do this instead:

x.Name.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0
x.EmployeeNumber.ToString().IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0

Or you could use StartsWith instead of IndexOf.

Edit: Another problem with List Controls with large amounts of data in them is that it takes a long time to render. So if you have it unfiltered when you start and Silverlight or WCF or whatever has to render all 1000 into the control even though you don't see all of them, it can take a little bit of time. Silverlight 3 has UI Virtualization, which would probably be the best optimization you could do here.

Mike Blandford
It's currently being filled by a paged gateway, so no issues there.
Slipfish
+1  A: 

I know this is an old post but I was using it to help me with the filtering aspect and noticed that SlipFish was creating the ObservableCollection by looping round the IEnumerable collection.

As the ObservableCollection constructor accepts an IEnumerable collection the ObservableCollection could be created like this:

FilteredEmployees = new ObservableCollection<EmployeeServicesData>(filter);
EzaBlade